home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / samba / patches / samba-1.000 / samba-1
Text File  |  1996-07-18  |  418KB  |  13,301 lines

  1. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/README samba-1.9.16alpha11/README
  2. --- samba-1.9.16alpha10/README    Tue May 28 23:37:21 1996
  3. +++ samba-1.9.16alpha11/README    Sun Jun 30 15:17:17 1996
  4. @@ -10,21 +10,27 @@
  5.  WHAT CAN SAMBA DO?
  6.  ==================
  7.  
  8. -Here is a very short list of what samba includes, and what it does
  9. +Here is a very short list of what samba includes, and what it does. 
  10.  
  11. -- a SMB server, to provide LanManager style file and print services to PCs
  12. +- a SMB server, to provide Windows NT and LAN Manager-style file and print 
  13. +  services to SMB clients such as Windows 95, Warp Server, smbfs and others.
  14.  
  15. -- a Netbios (rfc1001/1002) nameserver
  16. +- a Netbios (rfc1001/1002) nameserver, which among other things gives 
  17. +  browsing support. Samba can be the master browser on your LAN if you wish.
  18.  
  19.  - a ftp-like SMB client so you can access PC resources (disks and
  20. -printers) from unix
  21. +printers) from unix, Netware and other operating systems
  22.  
  23.  - a tar extension to the client for backing up PCs
  24.  
  25. +For a much better overview have a look at the web site at
  26. +http://samba.canberra.edu.au/pub/samba, and browse the user survey.
  27. +
  28.  Related packages include:
  29.  
  30. -- ksmbfs, a linux-only filesystem allowing you to mount remote SMB
  31. -filesystems from PCs on your linux box
  32. +- smbfs, a linux-only filesystem allowing you to mount remote SMB
  33. +filesystems from PCs on your linux box. This is included as standard with
  34. +Linux 2.0 and later.
  35.  
  36.  - tcpdump-smb, a extension to tcpdump to allow you to investigate SMB
  37.  networking problems over netbeui and tcp/ip
  38. @@ -47,7 +53,8 @@
  39.  
  40.  Remember that free software of this kind lives or dies by the response
  41.  we get. If noone tells us they like it then we'll probably move onto
  42. -something else.
  43. +something else. However, as you can see from the user survey quite a lot of 
  44. +people do seem to like it at the moment :-)
  45.  
  46.  Andrew Tridgell
  47.  Email: samba-bugs@samba.anu.edu.au
  48. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/docs/announce samba-1.9.16alpha11/docs/announce
  49. --- samba-1.9.16alpha10/docs/announce    Tue May 28 23:37:23 1996
  50. +++ samba-1.9.16alpha11/docs/announce    Sun Jun 30 15:17:19 1996
  51. @@ -4,19 +4,21 @@
  52.  What is Samba?
  53.  --------------
  54.  
  55. -Samba is a Unix based SMB file server. This allows a Unix host to
  56. -act as a file and print server for SMB clients. This includes
  57. +Samba is a SMB file server that runs on Unix and other operating systems. 
  58. +It allows these operating systems (currently Unix, Netware, OS/2 and 
  59. +AmigaDOS) to act as a file and print server for SMB clients. There are many
  60.  Lan-Manager compatible clients such as LanManager for DOS, Windows for
  61.  Workgroups, Windows NT, Windows 95, OS/2, Pathworks and many more.
  62.  
  63. -The package also includes a Unix SMB client and a netbios nameserver.
  64. +The package also includes a SMB client for accessing other SMB servers 
  65. +and a netbios nameserver for browsing support.
  66.  
  67.  What can it do for me?
  68.  ----------------------
  69.  
  70.  If you have any PCs running SMB clients, such as a PC running Windows
  71. -for Workgroups, then you can mount file space or printers from a unix
  72. -host, so that directories, files and printers on the unix host are
  73. +for Workgroups, then you can mount file space or printers on a Samba
  74. +host, so that directories, files and printers on the host are
  75.  available on the PC.
  76.  
  77.  The client part of the package will also allow you to attach to other
  78. @@ -31,7 +33,7 @@
  79.  
  80.  Samba supports many features that are not supported in other SMB
  81.  implementations (all of which are commercial). Some of it's features
  82. -include host as well as username/password security, a unix client,
  83. +include host as well as username/password security, a client,
  84.  automatic home directory exporting, automatic printer exporting, dead
  85.  connection timeouts, umask support, guest connections, name mangling
  86.  and hidden and system attribute mapping. Look at the man pages
  87. @@ -66,7 +68,7 @@
  88.  GNU Public licence in source code form at no cost. Please read the
  89.  file COPYING that comes with the package for more information.
  90.  
  91. -What flavours of unix does it support?
  92. +What operating systems does it support?
  93.  ---------------------------------------
  94.  
  95.  The code has been written to be as portable as possible. It has been
  96. @@ -79,7 +81,9 @@
  97.  Domain/OS and DGUX.
  98.  
  99.  Some of these have received more testing than others. If it doesn't
  100. -work with your unix then it should be easy to fix.
  101. +work with your unix then it should be easy to fix. It has also been ported
  102. +to Netware, OS/2 and the Amiga. A VMS port is underway. See the web site
  103. +for more details.
  104.  
  105.  Who wrote it?
  106.  -------------
  107. @@ -125,5 +129,5 @@
  108.  A WWW site with lots of Samba info can be found at 
  109.  http://samba.canberra.edu.au/pub/samba/
  110.  
  111. -Andrew Tridgell (Contact: samba-bugs@anu.edu.au)
  112. -January 1995
  113. +The Samba Team (Contact: samba-bugs@anu.edu.au)
  114. +June 1996
  115. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/docs/security_level.txt samba-1.9.16alpha11/docs/security_level.txt
  116. --- samba-1.9.16alpha10/docs/security_level.txt    Thu May 30 10:05:51 1996
  117. +++ samba-1.9.16alpha11/docs/security_level.txt    Sun Jun 30 15:17:19 1996
  118. @@ -42,14 +42,14 @@
  119.  operation. The client is expecting a password to be associated with
  120.  each share, independent of the user. This means that samba has to work
  121.  out what username the client probably wants to use. It is never
  122. -explicitly sent the username. A "real" SMB server like NT actually
  123. -associates passwords directly with shares in share level security, but
  124. +explicitly sent the username. Some commercial SMB servers such as NT actually
  125. +associate passwords directly with shares in share level security, but
  126.  samba always uses the unix authentication scheme where it is a
  127.  username/password that is authenticated, not a "share/password".
  128.  
  129.  Many clients send a "session setup" even if the server is in share
  130.  level security. They normally send a valid username but no
  131. -password. Samba records this username is a list of "possible
  132. +password. Samba records this username in a list of "possible
  133.  usernames". When the client then does a "tree connection" it also adds
  134.  to this list the name of the share they try to connect to (useful for
  135.  home directories) and any users listed in the "user =" smb.conf
  136. @@ -75,4 +75,5 @@
  137.  enabled to support this feature, and you have to maintain a separate
  138.  smbpasswd file with SMB style encrypted passwords. It is
  139.  cryptographically impossible to translate from unix style encryption
  140. -to SMB style encryption.
  141. +to SMB style encryption, although there are some fairly simple management
  142. +schemes by which the two could be kept in sync.
  143. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/examples/simple/smb.conf samba-1.9.16alpha11/examples/simple/smb.conf
  144. --- samba-1.9.16alpha10/examples/simple/smb.conf    Sat May  4 17:50:25 1996
  145. +++ samba-1.9.16alpha11/examples/simple/smb.conf    Mon Jul 15 17:54:57 1996
  146. @@ -80,11 +80,13 @@
  147.     writable = no
  148.     create mode = 0700
  149.  
  150. -; you might also want this one
  151. +; you might also want this one, notice that it is read only so as not to give
  152. +; people without an account write access. 
  153. +;
  154.  ; [tmp]
  155.  ;   comment = Temporary file space
  156.  ;   path = /tmp
  157. -;   read only = no
  158. +;   read only = yes
  159.  ;   public = yes
  160.  
  161.  ;
  162. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/Makefile samba-1.9.16alpha11/source/Makefile
  163. --- samba-1.9.16alpha10/source/Makefile    Mon Jun 10 15:18:47 1996
  164. +++ samba-1.9.16alpha11/source/Makefile    Thu Jul 18 20:53:13 1996
  165. @@ -1,6 +1,6 @@
  166.  ###########################################################################
  167.  # Makefile for Samba SMB client/server for unix
  168. -# Copyright Andrew Tridgell 1992,1993,1994
  169. +# Copyright Andrew Tridgell 1992-1996
  170.  ###########################################################################
  171.  
  172.  # The base manpages directory to put the man pages in
  173. @@ -101,6 +101,15 @@
  174.  #VTP_OBJ = vt_mode.o
  175.  ######################################
  176.  
  177. +######################################
  178. +# WHICH AWK? awk is used for automatic prototype generation. GNU awk works
  179. +# where inferior awks don't. Sun is one manufacturer who supplies both
  180. +# a broken awk called 'awk' and a fixed one called 'nawk'. mkproto.awk will
  181. +# only work with the latter, and even that isn't as good as free GNU awk.
  182. +#
  183. +# Leave this uncommented; the OS-specific stuff will override it if required
  184. +AWK = awk
  185. +######################################
  186.  
  187.  #####################################
  188.  # WHICH OPERATING SYSTEM?
  189. @@ -148,7 +157,7 @@
  190.  # contributed by Andrew.Tridgell@anu.edu.au
  191.  # FLAGSM = -DSUNOS4
  192.  # LIBSM =   
  193. -
  194. +# AWK = nawk 
  195.  
  196.  # Use this for Linux with shadow passwords
  197.  # contributed by Andrew.Tridgell@anu.edu.au
  198. @@ -177,6 +186,7 @@
  199.  # contributed by Andrew.Tridgell@anu.edu.au
  200.  # FLAGSM = -DSUNOS5 -DSHADOW_PWD -DNETGROUP 
  201.  # LIBSM = -lsocket -lnsl
  202. +# AWK = nawk 
  203.  
  204.  
  205.  # This is for SVR4
  206. @@ -491,8 +501,8 @@
  207.      @echo "Using CFLAGS = $(CFLAGS)"
  208.      @echo "Using LIBS = $(LIBS)"
  209.  
  210. -INCLUDES1 = version.h local.h includes.h smb.h loadparm.h params.h smbpass.h
  211. -INCLUDES2 = pcap.h trans2.h reply.h
  212. +INCLUDES1 = version.h local.h includes.h smb.h smbpass.h
  213. +INCLUDES2 = trans2.h reply.h
  214.  INCLUDES = $(INCLUDES1) $(INCLUDES2)
  215.  
  216.  UTILOBJ1 = util.o system.o charset.o kanji.o fault.o smbencrypt.o charcnv.o
  217. @@ -502,8 +512,10 @@
  218.  SMBDOBJ1 = $(PARAMOBJ) trans2.o message.o dir.o printing.o locking.o
  219.  SMBDOBJ2 = ipc.o reply.o mangle.o chgpasswd.o password.o quotas.o uid.o
  220.  SMBDOBJ = predict.o $(SMBDOBJ1) $(SMBDOBJ2) $(VTP_OBJ)
  221. -NMBDOBJ1 = $(UTILOBJ) nmblib.o nameresp.o nmbsync.o nameannounce.o namedb.o nameelect.o
  222. -NMBDOBJ = $(NMBDOBJ1) namework.o nameserv.o clientutil.o
  223. +NMBDOBJ1 = nmblib.o namepacket.o nameresp.o nmbsync.o nameannounce.o nameelect.o
  224. +NMBDOBJ2 = namedbresp.o namedbwork.o namedbserver.o namedbsubnet.o namedbname.o 
  225. +NMBDOBJ3 = nameservresp.o nameservreply.o namelogon.o namebrowse.o namework.o nameserv.o clientutil.o
  226. +NMBDOBJ = $(UTILOBJ) $(NMBDOBJ1) $(NMBDOBJ2) $(NMBDOBJ3)
  227.  .SUFFIXES:
  228.  .SUFFIXES: .c .o .h
  229.  
  230. @@ -553,7 +565,7 @@
  231.      @$(SHELL) $(srcdir)installbin.sh $(INSTALLPERMS) $(BASEDIR) $(BINDIR) $(LIBDIR) $(VARDIR) $(PROGS)
  232.  
  233.  installscripts:
  234. -    @$(SHELL) $(srcdir)installscripts.sh $(INSTALLPERMS) $(BINDIR) $(srcdir)
  235. +    @$(SHELL) $(srcdir)installscripts.sh $(INSTALLPERMS) $(BINDIR) $(SCRIPTS)
  236.  
  237.  # revert to the previously installed version
  238.  revert:
  239. @@ -562,11 +574,23 @@
  240.  installman:
  241.      @$(SHELL) $(srcdir)installman.sh $(MANDIR) $(srcdir)
  242.  
  243. +uninstall: uninstallman uninstallbin uninstallscripts
  244. +
  245. +uninstallman:
  246. +    @$(SHELL) $(srcdir)uninstallman.sh $(MANDIR) $(srcdir)
  247. +
  248. +uninstallbin:
  249. +    @$(SHELL) $(srcdir)uninstallbin.sh $(INSTALLPERMS) $(BASEDIR) $(BINDIR) $(LIBDIR) $(VARDIR) $(PROGS)
  250. +
  251. +uninstallscripts:
  252. +    @$(SHELL) $(srcdir)uninstallscripts.sh $(INSTALLPERMS) $(BINDIR) $(SCRIPTS)
  253. +
  254.  clean:
  255.      rm -f core *.o *~ $(PROGS)
  256.  
  257.  proto:
  258. -    cat *.c | awk -f mkproto.awk > proto.h
  259. +    @$(SHELL) $(srcdir)checkos.sh $(FLAGSM)
  260. +    $(AWK) -f mkproto.awk *.c > proto.h
  261.  
  262.  realclean: clean
  263.  
  264. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/access.c samba-1.9.16alpha11/source/access.c
  265. --- samba-1.9.16alpha10/source/access.c    Mon Jun 10 15:18:48 1996
  266. +++ samba-1.9.16alpha11/source/access.c    Mon Jul 15 17:55:03 1996
  267. @@ -5,7 +5,7 @@
  268.  The code is used here with permission.
  269.  
  270.  The code has been considerably changed from the original. Bug reports
  271. -should be sent to Andrew.Tridgell@anu.edu.au
  272. +should be sent to samba-bugs@samba.anu.edu.au
  273.  */
  274.  
  275.  #include "includes.h"
  276. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/change-log samba-1.9.16alpha11/source/change-log
  277. --- samba-1.9.16alpha10/source/change-log    Wed May 29 14:28:46 1996
  278. +++ samba-1.9.16alpha11/source/change-log    Mon Jul 15 17:55:03 1996
  279. @@ -1,10 +1,13 @@
  280. -Change Log for Samba
  281. +SUPERCEDED Change Log for Samba
  282. +^^^^^^^^^^
  283.  
  284.  Unless otherwise attributed, all changes were made by 
  285. -Andrew.Tridgell@anu.edu.au
  286. +Andrew.Tridgell@anu.edu.au. All bugs to samba-bugs@samba.anu.edu.au.
  287.  
  288.  NOTE: THIS LOG IS IN CHRONOLOGICAL ORDER
  289.  
  290. +NOTE: From now on the cvs.log file will be used to give a complete log of
  291. +changes to samba. This change-log is now obsolete.
  292.  
  293.  1.5.00    announced to mailing list
  294.  
  295. @@ -1872,4 +1875,4 @@
  296.       Tony Aiuto (tony@ics.com)
  297.  
  298.  make max disk size local
  299. -    
  300. \ No newline at end of file
  301. +    
  302. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/checkos.sh samba-1.9.16alpha11/source/checkos.sh
  303. --- samba-1.9.16alpha10/source/checkos.sh    Sat May  4 17:50:25 1996
  304. +++ samba-1.9.16alpha11/source/checkos.sh    Mon Jul 15 17:55:03 1996
  305. @@ -5,11 +5,11 @@
  306.  You forgot to uncomment a host type and flags in the Makefile. If your
  307.  host type does not appear in the Makefile then choose one that you
  308.  think is similar and once you have it working then add a new host type
  309. -to the Makefile and includes.h. Please also send me the output of the
  310. +to the Makefile and includes.h. Please also send us the output of the
  311.  command "uname" on your system so this can be automated at some future
  312.  time. 
  313.  
  314. -Andrew.Tridgell@anu.edu.au
  315. +samba-bugs@samba.anu.edu.au
  316.  =====================================================================
  317.  EOF
  318.  exit 1
  319. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/client.c samba-1.9.16alpha11/source/client.c
  320. --- samba-1.9.16alpha10/source/client.c    Mon Jun 10 15:18:49 1996
  321. +++ samba-1.9.16alpha11/source/client.c    Thu Jul 18 20:53:15 1996
  322. @@ -2874,6 +2874,21 @@
  323.    return(True);
  324.  }
  325.  
  326. +static struct {
  327. +  int prot;
  328. +  char *name;
  329. +} prots[] = {
  330. +  {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
  331. +  {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
  332. +  {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
  333. +  {PROTOCOL_LANMAN1,"LANMAN1.0"},
  334. +  {PROTOCOL_LANMAN2,"LM1.2X002"},
  335. +  {PROTOCOL_LANMAN2,"Samba"},
  336. +  {PROTOCOL_NT1,"NT LM 0.12"},
  337. +  {PROTOCOL_NT1,"NT LANMAN 1.0"},
  338. +  {-1,NULL}
  339. +};
  340. +
  341.  
  342.  /****************************************************************************
  343.  send a login command
  344. @@ -2887,22 +2902,6 @@
  345.    int sec_mode=0;
  346.    int crypt_len;
  347.    int max_vcs=0;
  348. -  struct {
  349. -    int prot;
  350. -    char *name;
  351. -  }
  352. -  prots[] = 
  353. -    {
  354. -      {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
  355. -      {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
  356. -      {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
  357. -      {PROTOCOL_LANMAN1,"LANMAN1.0"},
  358. -      {PROTOCOL_LANMAN2,"LM1.2X002"},
  359. -      {PROTOCOL_LANMAN2,"Samba"},
  360. -      {PROTOCOL_NT1,"NT LM 0.12"},
  361. -      {PROTOCOL_NT1,"NT LANMAN 1.0"},
  362. -      {-1,NULL}
  363. -    };
  364.    char *pass = NULL;  
  365.    pstring dev;
  366.    char *p;
  367. @@ -3586,7 +3585,7 @@
  368.  /****************************************************************************
  369.  try and browse available connections on a host
  370.  ****************************************************************************/
  371. -static BOOL list_servers()
  372. +static BOOL list_servers(char *wk_grp)
  373.  {
  374.    char *rparam = NULL;
  375.    char *rdata = NULL;
  376. @@ -3601,7 +3600,7 @@
  377.    p = param;
  378.    SSVAL(p,0,0x68); /* api number */
  379.    p += 2;
  380. -  strcpy(p,"WrLehDO");
  381. +  strcpy(p,"WrLehDz");
  382.    p = skip_string(p,1);
  383.  
  384.    strcpy(p,"B16BBDz");
  385. @@ -3616,6 +3615,11 @@
  386.  
  387.    SIVAL(p,0,SV_TYPE_ALL);
  388.  
  389. +  p += 4;
  390. +
  391. +  strcpy(p, wk_grp);
  392. +  p = skip_string(p,1);
  393. +
  394.    if (call_api(PTR_DIFF(p+4,param),0,
  395.             8,10000,
  396.             &rprcnt,&rdrcnt,
  397. @@ -3652,7 +3656,7 @@
  398.    if (rparam) {free(rparam); rparam = NULL;}
  399.    if (rdata) {free(rdata); rdata = NULL;}
  400.  
  401. -  SIVAL(p,0,SV_TYPE_DOMAIN_ENUM);
  402. +  SIVAL(p,0,0x7fffffff);
  403.  
  404.    if (call_api(PTR_DIFF(p+4,param),0,
  405.             8,10000,
  406. @@ -4392,9 +4396,9 @@
  407.          sleep(1);
  408.          browse_host(True);
  409.        }
  410. -      if (!list_servers()) {
  411. +      if (!list_servers(workgroup)) {
  412.          sleep(1);
  413. -        list_servers();
  414. +        list_servers(workgroup);
  415.        }
  416.  
  417.        send_logout();
  418. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/cvs.log samba-1.9.16alpha11/source/cvs.log
  419. --- samba-1.9.16alpha10/source/cvs.log    Mon Jun 10 15:21:07 1996
  420. +++ samba-1.9.16alpha11/source/cvs.log    Thu Jul 18 20:54:26 1996
  421. @@ -1574,3 +1574,822 @@
  422.  Log Message:
  423.  preparing for release of 1.9.16alpha10
  424.  
  425. +
  426. +****************************************
  427. +Date:    Monday June 10, 1996 @ 16:08
  428. +Author:    tridge
  429. +
  430. +Update of /data/cvs/samba/source
  431. +In directory arvidsjaur:/var/tmp/cvs-serv6264
  432. +
  433. +Modified Files:
  434. +    nameannounce.c namedb.c nameelect.c 
  435. +Log Message:
  436. +minor patch to allow host announcements to remote subnets
  437. +
  438. +
  439. +
  440. +****************************************
  441. +Date:    Wednesday June 12, 1996 @ 11:46
  442. +Author:    tridge
  443. +
  444. +Update of /data/cvs/samba/source
  445. +In directory arvidsjaur:/var/tmp/cvs-serv19858
  446. +
  447. +Modified Files:
  448. +    charset.c 
  449. +Log Message:
  450. +demo of cvs - ignore
  451. +
  452. +
  453. +
  454. +****************************************
  455. +Date:    Friday June 14, 1996 @ 14:20
  456. +Author:    samba-bugs
  457. +
  458. +Update of /data/cvs/samba/source
  459. +In directory arvidsjaur:/var/tmp/cvs-serv11409/samba/source
  460. +
  461. +Modified Files:
  462. +    Makefile 
  463. +Log Message:
  464. +Added option for specifying awk executable if not 'awk' initially for SunOSxx
  465. +Dan Shearer 14 June 96
  466. +
  467. +
  468. +
  469. +****************************************
  470. +Date:    Tuesday June 18, 1996 @ 0:10
  471. +Author:    samba-bugs
  472. +
  473. +Update of /data/cvs/samba/source
  474. +In directory arvidsjaur:/var/tmp/cvs-serv9310/samba/source
  475. +
  476. +Modified Files:
  477. +    Makefile mkproto.awk 
  478. +Log Message:
  479. +Added source filename to give crude index
  480. +Dan 17 June 1996
  481. +
  482. +
  483. +
  484. +****************************************
  485. +Date:    Tuesday June 18, 1996 @ 1:36
  486. +Author:    samba-bu
  487. +
  488. +Update of /data/cvs/samba/source
  489. +In directory arvidsjaur:/samba/samba-bugs/samba/source
  490. +
  491. +Modified Files:
  492. +    Makefile 
  493. +Log Message:
  494. +Fixed stupid bug introduced minutes ago
  495. +Dan
  496. +
  497. +
  498. +
  499. +****************************************
  500. +Date:    Wednesday June 19, 1996 @ 22:23
  501. +Author:    tridge
  502. +
  503. +Update of /data/cvs/samba/source
  504. +In directory arvidsjaur:/var/tmp/cvs-serv29445
  505. +
  506. +Modified Files:
  507. +    locking.c printing.c 
  508. +Log Message:
  509. +- change date as a demo for john
  510. +- modified plp printing parser to work on my system
  511. +
  512. +
  513. +
  514. +****************************************
  515. +Date:    Wednesday June 19, 1996 @ 22:27
  516. +Author:    samba-bugs
  517. +
  518. +Update of /data/cvs/samba/source
  519. +In directory arvidsjaur:/var/tmp/cvs-serv29534
  520. +
  521. +Modified Files:
  522. +    smbtar 
  523. +Log Message:
  524. + - deleted reduntant blank line at end of file (JHT)
  525. +
  526. +
  527. +
  528. +****************************************
  529. +Date:    Wednesday June 19, 1996 @ 23:23
  530. +Author:    samba-bugs
  531. +
  532. +Update of /data/cvs/samba
  533. +In directory arvidsjaur:/var/tmp/cvs-serv30708/samba
  534. +
  535. +Modified Files:
  536. +    README 
  537. +Log Message:
  538. +Basic doc changes to keep up to date.
  539. +
  540. +Dan
  541. +
  542. +
  543. +
  544. +****************************************
  545. +Date:    Wednesday June 19, 1996 @ 23:23
  546. +Author:    samba-bugs
  547. +
  548. +Update of /data/cvs/samba/docs
  549. +In directory arvidsjaur:/var/tmp/cvs-serv30708/samba/docs
  550. +
  551. +Modified Files:
  552. +    announce security_level.txt 
  553. +Log Message:
  554. +Basic doc changes to keep up to date.
  555. +
  556. +Dan
  557. +
  558. +
  559. +
  560. +****************************************
  561. +Date:    Wednesday June 19, 1996 @ 23:23
  562. +Author:    samba-bugs
  563. +
  564. +Update of /data/cvs/samba/source
  565. +In directory arvidsjaur:/var/tmp/cvs-serv30708/samba/source
  566. +
  567. +Modified Files:
  568. +    change-log proto.h system.c 
  569. +Log Message:
  570. +Basic doc changes to keep up to date.
  571. +
  572. +Dan
  573. +
  574. +
  575. +
  576. +****************************************
  577. +Date:    Sunday June 30, 1996 @ 4:49
  578. +Author:    samba-bugs
  579. +
  580. +Update of /data/cvs/samba/source
  581. +In directory arvidsjaur:/var/tmp/cvs-serv13629
  582. +
  583. +Modified Files:
  584. +    Makefile loadparm.c mkproto.awk nameannounce.c namedb.c 
  585. +    nameelect.c nameresp.c nameserv.c nameserv.h namework.c nmbd.c 
  586. +    nmblookup.c nmbsync.c proto.h smb.h 
  587. +Log Message:
  588. +
  589. +
  590. +luke's first attempt at using cvs
  591. +
  592. +accidentally updated the Makefile
  593. +
  594. +updated the name database structure (again!). this time, there is one
  595. +name database per local interface. there is also a pseudo-interface on
  596. +ip 255.255.255.255. its purpose is to store WINS name entries. all the
  597. +local interface name databases store SELF names only. the WINS name
  598. +database stores non-special browser names.
  599. +
  600. +added wins.dat file: records WINS entries in ascii format. this is reloaded
  601. +when nmbd restarts.
  602. +
  603. +added repeating code for response packets. timer is in seconds only at the
  604. +moment.
  605. +
  606. +updated the response queue code to deal with samba registering with a
  607. +WINS server a bit better (added more cases when a response isn't received).
  608. +tidied up the response packet processing code and expire_response_queue()
  609. +code. added cross references between response received and await-response
  610. +expired code.
  611. +
  612. +added over-zealous code that checks all machines that register with samba
  613. +as a WINS server (every 10 minutes i think): to see whether they are still
  614. +alive or not (see rfc1001.txt)
  615. +
  616. +bug reported by terry@ren.pc.athabascau.ca: DNSFAILed names _stay_ as
  617. +DNSFAIL, even though the machine may come back up and REGISTER.
  618. +
  619. +removed update_from_reg() function. it's not necessary, and it does too much.
  620. +
  621. +added code that announces on each local interface samba's ttl as zero and
  622. +servertype as zero when nmbd is kill -TERMed
  623. +
  624. +first attempt at putting the first functionality of samba browsing back in
  625. +(remote subnets should have samba appear in a workgroup specified through
  626. +the lmhosts file)
  627. +
  628. +lots of other miscellaneous tidying up / chopping about.
  629. +
  630. +
  631. +
  632. +****************************************
  633. +Date:    Sunday June 30, 1996 @ 5:26
  634. +Author:    samba-bugs
  635. +
  636. +Update of /data/cvs/samba/source
  637. +In directory arvidsjaur:/var/tmp/cvs-serv14098/samba/source
  638. +
  639. +Modified Files:
  640. +    Makefile interface.c 
  641. +Log Message:
  642. +
  643. +
  644. +added local and remote interfaces (didn't get done in first attempt)
  645. +
  646. +
  647. +
  648. +****************************************
  649. +Date:    Sunday June 30, 1996 @ 21:00
  650. +Author:    samba-bugs
  651. +
  652. +Update of /data/cvs/samba/source
  653. +In directory arvidsjaur:/var/tmp/cvs-serv9252
  654. +
  655. +Modified Files:
  656. +    Makefile 
  657. +Log Message:
  658. +
  659. +
  660. +
  661. +
  662. +****************************************
  663. +Date:    Tuesday July 2, 1996 @ 4:22
  664. +Author:    samba-bugs
  665. +
  666. +Update of /data/cvs/samba/source
  667. +In directory arvidsjaur:/var/tmp/cvs-serv1723
  668. +
  669. +Added Files:
  670. +    nameresp.doc nameserv.doc 
  671. +Log Message:
  672. +
  673. +
  674. +first draft of low-level design documents describing the operation of
  675. +nameserv.c and nameresp.c and their interaction with the rest of nmbd.
  676. +
  677. +
  678. +
  679. +****************************************
  680. +Date:    Tuesday July 2, 1996 @ 4:29
  681. +Author:    samba-bugs
  682. +
  683. +Update of /data/cvs/samba/source
  684. +In directory arvidsjaur:/var/tmp/cvs-serv1885
  685. +
  686. +Modified Files:
  687. +    nameresp.c nameserv.c proto.h 
  688. +Log Message:
  689. +
  690. +
  691. +updated the NetBIOS code due to some bugs found by writing the first draft
  692. +of the low level design docs.
  693. +
  694. +
  695. +
  696. +****************************************
  697. +Date:    Tuesday July 2, 1996 @ 4:53
  698. +Author:    samba-bugs
  699. +
  700. +Update of /data/cvs/samba/source
  701. +In directory arvidsjaur:/var/tmp/cvs-serv2248
  702. +
  703. +Modified Files:
  704. +    ipc.c 
  705. +Log Message:
  706. +
  707. +
  708. +patch to fix NetServerEnum with multiple workgroup lists kindly supplied.
  709. +it works for him. needs testing.
  710. +
  711. +
  712. +
  713. +****************************************
  714. +Date:    Wednesday July 3, 1996 @ 1:22
  715. +Author:    samba-bugs
  716. +
  717. +Update of /data/cvs/samba/source
  718. +In directory arvidsjaur:/var/tmp/cvs-serv22758
  719. +
  720. +Modified Files:
  721. +    nameresp.doc nameserv.doc 
  722. +Added Files:
  723. +    namework.doc 
  724. +Log Message:
  725. +
  726. +
  727. +updated low-level design documentation on nmbd. first draft of namework.doc
  728. +and updated the other two.
  729. +
  730. +lkcl
  731. +
  732. +
  733. +
  734. +****************************************
  735. +Date:    Wednesday July 3, 1996 @ 1:31
  736. +Author:    samba-bugs
  737. +
  738. +Update of /data/cvs/samba/source
  739. +In directory arvidsjaur:/var/tmp/cvs-serv22894
  740. +
  741. +Modified Files:
  742. +    nameserv.c namedb.c Makefile namework.c nameserv.h 
  743. +    nameannounce.c nameelect.c nameresp.c 
  744. +Added Files:
  745. +    namebrowse.c namelogon.c 
  746. +Log Message:
  747. +
  748. +
  749. +as a result of the writing of namework.doc, namework.c has been tidied up,
  750. +some bugs fixed / documented and some discrepancies noted down (in
  751. +namework.c as well as namework.doc)
  752. +
  753. +namebrowse.c and namelogon.c contain functions that were inappropriately
  754. +placed in namework.c. namebrowse.c contains browse sync queue management
  755. +functions that were inappropriately placed in namedb.c
  756. +
  757. +the 'cmd_type' member of response_record has been renamed to 'state'
  758. +because that more accurately reflects it purpose (not entirely. sigh).
  759. +
  760. +fixed a bug in nameserv.c that meant the previous version wouldn't
  761. +compile.
  762. +
  763. +there's probably a bit more...
  764. +
  765. +lkcl
  766. +
  767. +
  768. +
  769. +****************************************
  770. +Date:    Wednesday July 3, 1996 @ 11:58
  771. +Author:    tridge
  772. +
  773. +Update of /data/cvs/samba/source
  774. +In directory arvidsjaur:/var/tmp/cvs-serv29605
  775. +
  776. +Modified Files:
  777. +    client.c reply.c 
  778. +Log Message:
  779. +- moved the protocol defs in the client to keep sill C compilers happy
  780. +- added change for cnum range in reply_tdis()
  781. +
  782. +
  783. +
  784. +****************************************
  785. +Date:    Wednesday July 3, 1996 @ 12:39
  786. +Author:    tridge
  787. +
  788. +Update of /data/cvs/samba/source
  789. +In directory arvidsjaur:/var/tmp/cvs-serv30677
  790. +
  791. +Modified Files:
  792. +    Makefile proto.h 
  793. +Log Message:
  794. +fix Makefile - remove Lukes private stuff :-)
  795. +rerun proto generator
  796. +
  797. +
  798. +
  799. +****************************************
  800. +Date:    Wednesday July 3, 1996 @ 12:58
  801. +Author:    tridge
  802. +
  803. +Update of /data/cvs/samba/source
  804. +In directory arvidsjaur:/var/tmp/cvs-serv30965
  805. +
  806. +Modified Files:
  807. +    nameannounce.c 
  808. +Log Message:
  809. +fixed conflict with global variable updatecount
  810. +
  811. +
  812. +
  813. +****************************************
  814. +Date:    Wednesday July 3, 1996 @ 12:58
  815. +Author:    tridge
  816. +
  817. +Update of /data/cvs/samba/source
  818. +In directory arvidsjaur:/var/tmp/cvs-serv31015
  819. +
  820. +Modified Files:
  821. +    nameresp.c 
  822. +Log Message:
  823. +fixed conflict between two variables called d
  824. +
  825. +
  826. +
  827. +****************************************
  828. +Date:    Wednesday July 3, 1996 @ 12:58
  829. +Author:    tridge
  830. +
  831. +Update of /data/cvs/samba/source
  832. +In directory arvidsjaur:/var/tmp/cvs-serv31037
  833. +
  834. +Modified Files:
  835. +    proto.h 
  836. +Log Message:
  837. +generated new proto.h
  838. +
  839. +
  840. +
  841. +****************************************
  842. +Date:    Thursday July 4, 1996 @ 13:16
  843. +Author:    samba-bugs
  844. +
  845. +Update of /data/cvs/samba/source
  846. +In directory arvidsjaur:/var/tmp/cvs-serv22778/source
  847. +
  848. +Modified Files:
  849. +    Makefile access.c change-log checkos.sh 
  850. +Log Message:
  851. +Started uninstall in Makefile
  852. +Updated some email addresses
  853. +
  854. +
  855. +
  856. +****************************************
  857. +Date:    Thursday July 4, 1996 @ 13:22
  858. +Author:    samba-bugs
  859. +
  860. +Update of /data/cvs/samba/source
  861. +In directory arvidsjaur:/var/tmp/cvs-serv22827/source
  862. +
  863. +Modified Files:
  864. +    Makefile 
  865. +Log Message:
  866. +Put "which awk?" section in Makefile again
  867. +
  868. +Dan
  869. +
  870. +
  871. +
  872. +****************************************
  873. +Date:    Friday July 5, 1996 @ 5:19
  874. +Author:    samba-bugs
  875. +
  876. +Update of /data/cvs/samba/source
  877. +In directory arvidsjaur:/var/tmp/cvs-serv6347
  878. +
  879. +Modified Files:
  880. +    charset.c ipc.c namedb.c nameelect.c nameresp.c nameserv.c 
  881. +    nameserv.h nmbd.c nmbsync.c proto.h 
  882. +Log Message:
  883. +
  884. +modified become_master() to a state-based system. becoming a master
  885. +is now performed in stages: wait for each NetBIOS name to be
  886. +successfully registered before proceeding to the next stage.
  887. +
  888. +tied implicit name registration and release (broadcast method) to the
  889. +same piece of code as explicit method (via WINS server).
  890. +
  891. +created special_browser_name() function that checks __MSBROWSE__
  892. +name: this name is ignored by WINS servers apparently.
  893. +
  894. +fixed likely incompatibility between refresh_my_names() and add_my_names().
  895. +(netbios entries were unlikely to be refreshed).
  896. +
  897. +NOTE: none of these changes have been tested. at all.
  898. +
  899. +lkcl
  900. +
  901. +
  902. +
  903. +****************************************
  904. +Date:    Friday July 5, 1996 @ 5:40
  905. +Author:    samba-bugs
  906. +
  907. +Update of /data/cvs/samba/source
  908. +In directory arvidsjaur:/var/tmp/cvs-serv6805
  909. +
  910. +Modified Files:
  911. +    namebrowse.c proto.h 
  912. +Log Message:
  913. +
  914. +namebrowse.c was using variable work uninitialised.
  915. +remkproto'd proto.h
  916. +
  917. +lkcl
  918. +
  919. +
  920. +
  921. +****************************************
  922. +Date:    Friday July 5, 1996 @ 11:03
  923. +Author:    samba-bugs
  924. +
  925. +Update of /data/cvs/samba/source
  926. +In directory arvidsjaur:/var/tmp/cvs-serv10304/source
  927. +
  928. +Modified Files:
  929. +    Makefile 
  930. +Log Message:
  931. +Updated Makefile - removed loadparam.h and friends - not needed??
  932. +
  933. +
  934. +
  935. +****************************************
  936. +Date:    Friday July 5, 1996 @ 13:51
  937. +Author:    samba-bugs
  938. +
  939. +Update of /data/cvs/samba/source
  940. +In directory arvidsjaur:/var/tmp/cvs-serv12406
  941. +
  942. +Modified Files:
  943. +    Makefile installbin.sh installman.sh installscripts.sh 
  944. +Log Message:
  945. +Changed install scripts so they don't have hardcoded values
  946. +
  947. +Dan
  948. +
  949. +
  950. +
  951. +****************************************
  952. +Date:    Friday July 5, 1996 @ 13:53
  953. +Author:    samba-bugs
  954. +
  955. +Update of /data/cvs/samba/source
  956. +In directory arvidsjaur:/var/tmp/cvs-serv12511
  957. +
  958. +Added Files:
  959. +    uninstallbin.sh uninstallman.sh uninstallscripts.sh 
  960. +Log Message:
  961. +Added uninstallation from Makefile, either in parts or total uninstall
  962. +
  963. +Dan
  964. +
  965. +
  966. +
  967. +****************************************
  968. +Date:    Saturday July 6, 1996 @ 7:28
  969. +Author:    samba-bugs
  970. +
  971. +Update of /data/cvs/samba/source
  972. +In directory arvidsjaur:/var/tmp/cvs-serv28271
  973. +
  974. +Modified Files:
  975. +    Makefile 
  976. +Log Message:
  977. +Call checkos in "make proto" in case of OS with broken awk && forgetful user,
  978. +because it looks very much like an awk bug otherwise.
  979. +
  980. +Dan
  981. +
  982. +
  983. +
  984. +****************************************
  985. +Date:    Saturday July 6, 1996 @ 7:31
  986. +Author:    samba-bugs
  987. +
  988. +Update of /data/cvs/samba/source
  989. +In directory arvidsjaur:/var/tmp/cvs-serv28298
  990. +
  991. +Modified Files:
  992. +    Makefile 
  993. +Log Message:
  994. +Change awk to ($AWK) yet again :-)
  995. +
  996. +Dan
  997. +
  998. +
  999. +
  1000. +****************************************
  1001. +Date:    Sunday July 7, 1996 @ 22:36
  1002. +Author:    samba-bugs
  1003. +
  1004. +Update of /data/cvs/samba/source
  1005. +In directory arvidsjaur:/var/tmp/cvs-serv28811
  1006. +
  1007. +Modified Files:
  1008. +    Makefile nameannounce.c namebrowse.c nameelect.c nameresp.c 
  1009. +    nameresp.doc nameserv.c nameserv.doc nameserv.h namework.c 
  1010. +    namework.doc 
  1011. +Added Files:
  1012. +    nameannounce.doc namebrowse.doc namedbname.doc namedbresp.doc 
  1013. +    nameelect.doc namelogon.doc namepacket.doc namequery.doc 
  1014. +    nameservreply.doc nameservresp.doc 
  1015. +Log Message:
  1016. +
  1017. +
  1018. +tidied up: code shuffling and documentation.
  1019. +created namedb*.c nameservresp.c nameservreply.c and namepacket.c
  1020. +added modules to Makefile, downloading dan's current version first :-)
  1021. +shuffled docs to match source
  1022. +created more docs
  1023. +
  1024. +fixed bug in announce_backup() discovered when going nameannounce.doc:
  1025. +backup list requests to the master browser should be used when samba is
  1026. +not a master browser; backup list requests to the primary domain
  1027. +controller should be used when samba is not a primary domain controller.
  1028. +
  1029. +fixed bug in sync_server: it would never send MasterAnnounce packets.
  1030. +
  1031. +removed the code that ignored special browser names: these should only
  1032. +be ignored (except 0x1b names) when broadcasted name queries are sent,
  1033. +not when directed registration or directed queries are sent samba as a
  1034. +WINS server. (note: exactly what's going on is still uncertain).
  1035. +
  1036. +renamed NAME_QUERY_MST_SRV_CHK  to NAME_QUERY_PDC_SRV_CHK  (more accurate).
  1037. +renamed NAME_STATUS_MST_SRV_CHK to NAME_STATUS_PDC_SRV_CHK (more accurate).
  1038. +
  1039. +added secured WINS name registration: a new 'state' NAME_REGISTER_CHALLENGE;
  1040. +functions send_name_response(), response_name_query_register(); added
  1041. +sending of WAIT ACKNOWLEDGEMENT packet; added a reply_to_ip field to
  1042. +the response record structure so that after the name query challenge,
  1043. +you know who to inform of the outcome of that challenge.
  1044. +
  1045. +note: these are all currently untested modifications (yikes!)
  1046. +
  1047. +lkcl
  1048. +
  1049. +
  1050. +
  1051. +****************************************
  1052. +Date:    Sunday July 7, 1996 @ 23:29
  1053. +Author:    samba-bugs
  1054. +
  1055. +Update of /data/cvs/samba/source
  1056. +In directory arvidsjaur:/var/tmp/cvs-serv29341
  1057. +
  1058. +Modified Files:
  1059. +    Makefile namedb.c proto.h 
  1060. +Added Files:
  1061. +    namedbname.c namedbresp.c namedbserver.c namedbsubnet.c 
  1062. +    namedbwork.c namepacket.c nameservreply.c nameservresp.c 
  1063. +Log Message:
  1064. +
  1065. +added the recently shuffled and updated source files missed in the
  1066. +previous commit (see previous log message for details)
  1067. +
  1068. +fixed bug in nameservreply.c: wrong macro in use (RSSVAL not IVAL!).
  1069. +
  1070. +did another make proto
  1071. +
  1072. +lkcl
  1073. +
  1074. +
  1075. +
  1076. +****************************************
  1077. +Date:    Wednesday July 10, 1996 @ 4:01
  1078. +Author:    samba-bugs
  1079. +
  1080. +Update of /data/cvs/samba/source
  1081. +In directory arvidsjaur:/var/tmp/cvs-serv9536
  1082. +
  1083. +Modified Files:
  1084. +    nameannounce.c namedbname.c namedbresp.c namedbserver.c 
  1085. +    namedbsubnet.c namedbwork.c nameelect.c namepacket.c 
  1086. +    nameresp.c nameserv.c namework.c 
  1087. +Log Message:
  1088. +
  1089. +sorted out various timer delay bugs: nameannounce.c nameserv.c
  1090. +
  1091. +namedbname.c:search_for_name() wasn't looking for 0x1b as well as
  1092. +0x0 and 0x20 name types.
  1093. +
  1094. +reduced number of retransmissions of packets from 4 to 3 times.
  1095. +
  1096. +added code that ensures remote lmhosts entries don't get deleted when
  1097. +a master browser cannot be found on a remote subnet. stopped forcing
  1098. +an election on remote subnets if a master browser cannot be found.
  1099. +
  1100. +stopped browse list and wins list from being written out too frequently.
  1101. +
  1102. +only add samba's names to local interfaces.
  1103. +
  1104. +add 0x1c name if we are a domain logon machine (needs more exploration).
  1105. +
  1106. +why bother reloading services when receiving a SIGTERM?
  1107. +
  1108. +sort out add_my_name_entry() and remove_name_entry() to deal with
  1109. +broadcast, samba as a WINS and samba using a WINS. properly.
  1110. +
  1111. +added extra debug information to help with expected response queue code.
  1112. +updated debug comments in become_master().
  1113. +
  1114. +altered dump_names() DEBUG format. it looks prettier.
  1115. +altered wins.dat format to match DEBUG format.
  1116. +
  1117. +lkcl
  1118. +
  1119. +
  1120. +
  1121. +****************************************
  1122. +Date:    Wednesday July 10, 1996 @ 4:11
  1123. +Author:    samba-bugs
  1124. +
  1125. +Update of /data/cvs/samba/source
  1126. +In directory arvidsjaur:/var/tmp/cvs-serv9831
  1127. +
  1128. +Modified Files:
  1129. +    nmbd.c proto.h 
  1130. +Log Message:
  1131. +
  1132. +missed nmbd.c in previous update.
  1133. +did a make proto
  1134. +
  1135. +lkcl
  1136. +
  1137. +
  1138. +
  1139. +****************************************
  1140. +Date:    Thursday July 11, 1996 @ 4:48
  1141. +Author:    samba-bugs
  1142. +
  1143. +Update of /data/cvs/samba/source
  1144. +In directory arvidsjaur:/var/tmp/cvs-serv29974
  1145. +
  1146. +Modified Files:
  1147. +    ipc.c namedbresp.doc namedbsubnet.c nameelect.c nameelect.doc 
  1148. +    nameresp.c nameserv.c nameserv.doc nameservreply.c 
  1149. +    nameservreply.doc nameservresp.c nameservresp.doc proto.h 
  1150. +Removed Files:
  1151. +    namedb.c 
  1152. +Log Message:
  1153. +
  1154. +updated docs to match code mods from last two or three updates. done
  1155. +some more commenting of code to match docs.
  1156. +
  1157. +sorted some bugs.
  1158. +
  1159. +ipc BOOL domains was uninitialised.
  1160. +
  1161. +lkcl
  1162. +
  1163. +
  1164. +
  1165. +****************************************
  1166. +Date:    Thursday July 11, 1996 @ 23:55
  1167. +Author:    samba-bugs
  1168. +
  1169. +Update of /data/cvs/samba/examples/simple
  1170. +In directory arvidsjaur:/var/tmp/cvs-serv7090
  1171. +
  1172. +Modified Files:
  1173. +    smb.conf 
  1174. +Log Message:
  1175. +Modified demo smb.conf to not have /tmp writeable by everyone by default.
  1176. +According to server-linux some people seem to be uncommenting the example 
  1177. +[tmp] without thinking what it does  :-)
  1178. +
  1179. +Dan
  1180. +
  1181. +
  1182. +
  1183. +****************************************
  1184. +Date:    Thursday July 18, 1996 @ 4:33
  1185. +Author:    samba-bugs
  1186. +
  1187. +Update of /data/cvs/samba/source
  1188. +In directory arvidsjaur:/var/tmp/cvs-serv28303
  1189. +
  1190. +Modified Files:
  1191. +    client.c ipc.c nameannounce.c namedbname.c namedbserver.c 
  1192. +    nameelect.c namepacket.c namequery.c nameresp.c nameresp.doc 
  1193. +    nameserv.c nameserv.h nameservreply.c nameservresp.c 
  1194. +    namework.c nmbd.c nmblookup.c proto.h version.h 
  1195. +Log Message:
  1196. +
  1197. +lots of changes to nmbd
  1198. +
  1199. +lkcl
  1200. +
  1201. +
  1202. +
  1203. +****************************************
  1204. +Date:    Thursday July 18, 1996 @ 20:08
  1205. +Author:    tridge
  1206. +
  1207. +Update of /data/cvs/samba/source
  1208. +In directory arvidsjaur:/var/tmp/cvs-serv11425
  1209. +
  1210. +Modified Files:
  1211. +    client.c 
  1212. +Log Message:
  1213. +removed some debug stuff from luke
  1214. +
  1215. +
  1216. +
  1217. +****************************************
  1218. +Date:    Thursday July 18, 1996 @ 20:20
  1219. +Author:    tridge
  1220. +
  1221. +Update of /data/cvs/samba/source
  1222. +In directory arvidsjaur:/var/tmp/cvs-serv11854
  1223. +
  1224. +Modified Files:
  1225. +    Makefile includes.h namework.c proto.h smb.h smbpass.c 
  1226. +Log Message:
  1227. +minor cleanups ready for another release
  1228. +
  1229. +
  1230. +
  1231. +
  1232. +****************************************
  1233. +Date:    Thursday July 18, 1996 @ 20:53
  1234. +Author:    samba-bu
  1235. +
  1236. +Update of /data/cvs/samba/source
  1237. +In directory arvidsjaur:/samba/samba-bugs/samba/source
  1238. +
  1239. +Modified Files:
  1240. +    version.h 
  1241. +Log Message:
  1242. +preparing for release of 1.9.16alpha11
  1243. +
  1244. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/includes.h samba-1.9.16alpha11/source/includes.h
  1245. --- samba-1.9.16alpha10/source/includes.h    Thu Jun  6 21:57:20 1996
  1246. +++ samba-1.9.16alpha11/source/includes.h    Thu Jul 18 20:53:15 1996
  1247. @@ -984,9 +984,6 @@
  1248.  #include "nameserv.h"
  1249.  #include "proto.h"
  1250.  #include "byteorder.h"
  1251. -#ifdef SMB_PASSWD
  1252. -#include "smbpass.h"
  1253. -#endif
  1254.  
  1255.  #include "kanji.h"
  1256.  #include "charset.h"
  1257. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/installbin.sh samba-1.9.16alpha11/source/installbin.sh
  1258. --- samba-1.9.16alpha10/source/installbin.sh    Sat May  4 17:50:25 1996
  1259. +++ samba-1.9.16alpha11/source/installbin.sh    Mon Jul 15 17:55:03 1996
  1260. @@ -34,7 +34,9 @@
  1261.  cat << EOF
  1262.  ======================================================================
  1263.  The binaries are installed. You may restore the old binaries (if there
  1264. -were any) using the command "make revert"
  1265. +were any) using the command "make revert". You may uninstall the binaries
  1266. +using the command "make uninstallbin" or "make uninstall" to uninstall
  1267. +binaries, man pages and shell scripts.
  1268.  ======================================================================
  1269.  EOF
  1270.  
  1271. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/installman.sh samba-1.9.16alpha11/source/installman.sh
  1272. --- samba-1.9.16alpha10/source/installman.sh    Sat May  4 17:50:25 1996
  1273. +++ samba-1.9.16alpha11/source/installman.sh    Mon Jul 15 17:55:03 1996
  1274. @@ -1,4 +1,6 @@
  1275.  #!/bin/sh
  1276. +#5 July 96 Dan.Shearer@unisa.edu.au  removed hardcoded values
  1277. +
  1278.  MANDIR=$1
  1279.  SRCDIR=$2
  1280.  
  1281. @@ -8,28 +10,29 @@
  1282.  if [ ! -d $d ]; then
  1283.  mkdir $d
  1284.  if [ ! -d $d ]; then
  1285. -  echo Failed to make directory $d
  1286. +  echo Failed to make directory $d, does $USER have privileges?
  1287.    exit 1
  1288.  fi
  1289.  fi
  1290.  done
  1291.  
  1292. -cp $SRCDIR../docs/*.1 $MANDIR/man1
  1293. -cp $SRCDIR../docs/*.5 $MANDIR/man5
  1294. -cp $SRCDIR../docs/*.8 $MANDIR/man8
  1295. -cp $SRCDIR../docs/*.7 $MANDIR/man7
  1296. -echo Setting permissions on man pages
  1297. -chmod 0644 $MANDIR/man1/smbstatus.1
  1298. -chmod 0644 $MANDIR/man1/smbclient.1
  1299. -chmod 0644 $MANDIR/man1/smbrun.1
  1300. -chmod 0644 $MANDIR/man1/testparm.1
  1301. -chmod 0644 $MANDIR/man1/testprns.1
  1302. -chmod 0644 $MANDIR/man1/smbtar.1
  1303. -chmod 0644 $MANDIR/man5/smb.conf.5
  1304. -chmod 0644 $MANDIR/man7/samba.7
  1305. -chmod 0644 $MANDIR/man8/smbd.8
  1306. -chmod 0644 $MANDIR/man8/nmbd.8
  1307. +for sect in 1 5 7 8 ; do
  1308. +  for m in $MANDIR/man$sect ; do
  1309. +    for s in $SRCDIR../docs/*$sect; do
  1310. +      FNAME=$m/`basename $s`
  1311. +      cp $s $m || echo Cannot create $FNAME... does $USER have privileges?
  1312. +      chmod 0644 $FNAME
  1313. +    done
  1314. +  done
  1315. +done
  1316. +
  1317. +cat << EOF
  1318. +======================================================================
  1319. +The man pages have been installed. You may uninstall them using the command
  1320. +the command "make uninstallman" or make "uninstall" to uninstall binaries,
  1321. +man pages and shell scripts.
  1322. +======================================================================
  1323. +EOF
  1324.  
  1325. -echo Man pages installed
  1326.  exit 0
  1327.  
  1328. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/installscripts.sh samba-1.9.16alpha11/source/installscripts.sh
  1329. --- samba-1.9.16alpha10/source/installscripts.sh    Sat Jun  8 15:37:52 1996
  1330. +++ samba-1.9.16alpha11/source/installscripts.sh    Mon Jul 15 17:55:03 1996
  1331. @@ -1,26 +1,43 @@
  1332.  #!/bin/sh
  1333.  # this script courtesy of James_K._Foote.PARC@xerox.com
  1334. +# 5 July 96 Dan.Shearer@UniSA.Edu.Au  Don't hardcode script names, get from Make
  1335. +
  1336.  INSTALLPERMS=$1
  1337.  BINDIR=$2
  1338. -SRCDIR=$3
  1339. +
  1340. +shift
  1341. +shift
  1342.  
  1343.  echo Installing scripts in $BINDIR
  1344.  
  1345. -for d in $BINDIR; do
  1346. +for d in [ $BINDIR ]; do
  1347.   if [ ! -d $d ]; then
  1348.    mkdir $d
  1349.    if [ ! -d $d ]; then
  1350.      echo Failed to make directory $d
  1351. +    echo Have you run installbin first?
  1352.      exit 1
  1353.    fi
  1354.   fi
  1355.  done
  1356.  
  1357. -cp ${SRCDIR}smbtar $BINDIR
  1358. -cp ${SRCDIR}addtosmbpass $BINDIR
  1359. -echo Setting permissions on scripts
  1360. -chmod $INSTALLPERMS $BINDIR/smbtar
  1361. -chmod $INSTALLPERMS $BINDIR/addtosmbpass
  1362. +for p in $*; do
  1363. +  echo Installing $BINDIR/$p
  1364. +  cp $p $BINDIR/$p
  1365. +  if [ ! -f $BINDIR/$p ]; then
  1366. +    echo Cannot copy $p... does $USER have privileges?
  1367. +  fi
  1368. +  echo Setting permissions on $BINDIR/$p
  1369. +  chmod $INSTALLPERMS $BINDIR/$p
  1370. +done
  1371. +
  1372. +cat << EOF
  1373. +======================================================================
  1374. +The scripts have been installed. You may uninstall them using
  1375. +the command "make uninstallscripts" or "make install" to install binaries,
  1376. +man pages and shell scripts. You may recover the previous version (if any
  1377. +by "make revert".
  1378. +======================================================================
  1379. +EOF
  1380.  
  1381. -echo Scripts installed
  1382.  exit 0
  1383. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/interface.c samba-1.9.16alpha11/source/interface.c
  1384. --- samba-1.9.16alpha10/source/interface.c    Mon Jun 10 15:18:51 1996
  1385. +++ samba-1.9.16alpha11/source/interface.c    Sun Jun 30 15:17:24 1996
  1386. @@ -32,12 +32,9 @@
  1387.  static BOOL got_bcast=False;
  1388.  static BOOL got_nmask=False;
  1389.  
  1390. -static struct interface {
  1391. -  struct interface *next;
  1392. -  struct in_addr ip;
  1393. -  struct in_addr bcast;
  1394. -  struct in_addr nmask;
  1395. -} *interfaces = NULL;
  1396. +struct interface *local_interfaces  = NULL;
  1397. +struct interface *remote_interfaces = NULL;
  1398. +
  1399.  struct interface *last_iface;
  1400.  
  1401.  /****************************************************************************
  1402. @@ -253,13 +250,12 @@
  1403.  
  1404.  
  1405.  
  1406. -
  1407.  /****************************************************************************
  1408.  load a list of network interfaces
  1409.  ****************************************************************************/
  1410. -void load_interfaces(void)
  1411. +static void interpret_interfaces(char *s, struct interface **interfaces,
  1412. +        char *description)
  1413.  {
  1414. -  char *s = lp_interfaces();
  1415.    char *ptr = s;
  1416.    fstring token;
  1417.    struct interface *iface;
  1418. @@ -278,7 +274,7 @@
  1419.      /* maybe we already have it listed */
  1420.      {
  1421.        struct interface *i;
  1422. -      for (i=interfaces;i;i=i->next)
  1423. +      for (i=(*interfaces);i;i=i->next)
  1424.      if (ip_equal(ip,i->ip)) break;
  1425.        if (i) continue;
  1426.      }
  1427. @@ -299,18 +295,18 @@
  1428.      iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr;
  1429.      iface->next = NULL;
  1430.  
  1431. -    if (!interfaces) {
  1432. -      interfaces = iface;
  1433. +    if (!(*interfaces)) {
  1434. +      (*interfaces) = iface;
  1435.      } else {
  1436.        last_iface->next = iface;
  1437.      }
  1438.      last_iface = iface;
  1439. -    DEBUG(1,("Added interface ip=%s ",inet_ntoa(iface->ip)));
  1440. +    DEBUG(1,("Added %s ip=%s ",description,inet_ntoa(iface->ip)));
  1441.      DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast)));
  1442.      DEBUG(1,("nmask=%s\n",inet_ntoa(iface->nmask)));         
  1443.    }
  1444.  
  1445. -  if (interfaces) return;
  1446. +  if (*interfaces) return;
  1447.  
  1448.    /* setup a default interface */
  1449.    iface = (struct interface *)malloc(sizeof(*iface));
  1450. @@ -339,7 +335,7 @@
  1451.      DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip)));
  1452.    }
  1453.  
  1454. -  interfaces = last_iface = iface;
  1455. +  (*interfaces) = last_iface = iface;
  1456.  
  1457.    DEBUG(1,("Added interface ip=%s ",inet_ntoa(iface->ip)));
  1458.    DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast)));
  1459. @@ -348,6 +344,21 @@
  1460.  
  1461.  
  1462.  /****************************************************************************
  1463. +load the remote and local interfaces
  1464. +****************************************************************************/
  1465. +void load_interfaces(void)
  1466. +{
  1467. +  /* add the machine's interfaces to local interface structure*/
  1468. +  interpret_interfaces(lp_interfaces       (), &local_interfaces,
  1469. +                        "interface");
  1470. +
  1471. +  /* add all subnets to remote interfaces structure */
  1472. +  interpret_interfaces(lp_remote_interfaces(), &remote_interfaces,
  1473. +                        "remote subnet");
  1474. +}
  1475. +
  1476. +
  1477. +/****************************************************************************
  1478.    override the defaults
  1479.    **************************************************************************/
  1480.  void iface_set_default(char *ip,char *bcast,char *nmask)
  1481. @@ -375,7 +386,7 @@
  1482.  BOOL ismyip(struct in_addr ip)
  1483.  {
  1484.    struct interface *i;
  1485. -  for (i=interfaces;i;i=i->next)
  1486. +  for (i=local_interfaces;i;i=i->next)
  1487.      if (ip_equal(i->ip,ip)) return True;
  1488.    return False;
  1489.  }
  1490. @@ -386,7 +397,7 @@
  1491.  BOOL ismybcast(struct in_addr bcast)
  1492.  {
  1493.    struct interface *i;
  1494. -  for (i=interfaces;i;i=i->next)
  1495. +  for (i=local_interfaces;i;i=i->next)
  1496.      if (ip_equal(i->bcast,bcast)) return True;
  1497.    return False;
  1498.  }
  1499. @@ -399,7 +410,7 @@
  1500.    int ret = 0;
  1501.    struct interface *i;
  1502.  
  1503. -  for (i=interfaces;i;i=i->next)
  1504. +  for (i=local_interfaces;i;i=i->next)
  1505.      ret++;
  1506.    return ret;
  1507.  }
  1508. @@ -411,7 +422,7 @@
  1509.  {
  1510.    struct interface *i;
  1511.    
  1512. -  for (i=interfaces;i && n;i=i->next)
  1513. +  for (i=local_interfaces;i && n;i=i->next)
  1514.      n--;
  1515.  
  1516.    if (i) return &i->ip;
  1517. @@ -421,15 +432,14 @@
  1518.  static struct interface *iface_find(struct in_addr ip)
  1519.  {
  1520.    struct interface *i;
  1521. -  if (zero_ip(ip)) return interfaces;
  1522. +  if (zero_ip(ip)) return local_interfaces;
  1523.  
  1524. -  for (i=interfaces;i;i=i->next)
  1525. +  for (i=local_interfaces;i;i=i->next)
  1526.      if (same_net(i->ip,ip,i->nmask)) return i;
  1527.  
  1528. -  return interfaces;
  1529. +  return local_interfaces;
  1530.  }
  1531.  
  1532. -
  1533.  /* these 3 functions return the ip/bcast/nmask for the interface
  1534.     most appropriate for the given ip address */
  1535.  
  1536. @@ -447,5 +457,6 @@
  1537.  {
  1538.    return(&iface_find(ip)->ip);
  1539.  }
  1540. +
  1541.  
  1542.  
  1543. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/loadparm.c samba-1.9.16alpha11/source/loadparm.c
  1544. --- samba-1.9.16alpha10/source/loadparm.c    Mon Jun 10 15:18:53 1996
  1545. +++ samba-1.9.16alpha11/source/loadparm.c    Sun Jun 30 15:17:25 1996
  1546. @@ -129,6 +129,7 @@
  1547.    char *szSmbrun;
  1548.    char *szWINSserver;
  1549.    char *szInterfaces;
  1550. +  char *szRemoteInterfaces;
  1551.    int max_log_size;
  1552.    int mangled_stack;
  1553.    int max_xmit;
  1554. @@ -366,6 +367,7 @@
  1555.    {"null passwords",   P_BOOL,    P_GLOBAL, &Globals.bNullPasswords,    NULL},
  1556.    {"strip dot",        P_BOOL,    P_GLOBAL, &Globals.bStripDot,         NULL},
  1557.    {"interfaces",       P_STRING,  P_GLOBAL, &Globals.szInterfaces,      NULL},
  1558. +  {"remote interfaces",P_STRING,  P_GLOBAL, &Globals.szRemoteInterfaces,NULL},
  1559.    {"password server",  P_STRING,  P_GLOBAL, &Globals.szPasswordServer,  NULL},
  1560.    {"socket options",   P_GSTRING, P_GLOBAL, user_socket_options,        NULL},
  1561.    {"smbrun",           P_STRING,  P_GLOBAL, &Globals.szSmbrun,          NULL},
  1562. @@ -704,6 +706,7 @@
  1563.  FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript) 
  1564.  FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
  1565.  FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
  1566. +FN_GLOBAL_STRING(lp_remote_interfaces,&Globals.szRemoteInterfaces)
  1567.  
  1568.  FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
  1569.  FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
  1570. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/locking.c samba-1.9.16alpha11/source/locking.c
  1571. --- samba-1.9.16alpha10/source/locking.c    Mon Jun 10 15:18:54 1996
  1572. +++ samba-1.9.16alpha11/source/locking.c    Sun Jun 30 15:17:25 1996
  1573. @@ -2,7 +2,7 @@
  1574.     Unix SMB/Netbios implementation.
  1575.     Version 1.9.
  1576.     Locking functions
  1577. -   Copyright (C) Andrew Tridgell 1992-1995
  1578. +   Copyright (C) Andrew Tridgell 1992-1996
  1579.     
  1580.     This program is free software; you can redistribute it and/or modify
  1581.     it under the terms of the GNU General Public License as published by
  1582. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/mkproto.awk samba-1.9.16alpha11/source/mkproto.awk
  1583. --- samba-1.9.16alpha10/source/mkproto.awk    Mon Jun 10 15:18:54 1996
  1584. +++ samba-1.9.16alpha11/source/mkproto.awk    Sun Jun 30 15:17:25 1996
  1585. @@ -1,13 +1,17 @@
  1586. -# generate prototypes for Samba C code
  1587. -# tridge, June 1996
  1588. -
  1589.  BEGIN {
  1590.    inheader=0;
  1591. +  current_file="";
  1592.    print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */"
  1593.    print ""
  1594.  }
  1595.  
  1596.  {
  1597. +  if (FILENAME!=current_file) {
  1598. +    print ""
  1599. +    print "/*The following definitions come from ",FILENAME," */"
  1600. +    print ""
  1601. +    current_file=FILENAME
  1602. +  }
  1603.    if (inheader) {
  1604.      if (match($0,"[)][ \t]*$")) {
  1605.        inheader = 0;
  1606. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameannounce.c samba-1.9.16alpha11/source/nameannounce.c
  1607. --- samba-1.9.16alpha10/source/nameannounce.c    Mon Jun 10 15:18:55 1996
  1608. +++ samba-1.9.16alpha11/source/nameannounce.c    Thu Jul 18 20:53:15 1996
  1609. @@ -48,9 +48,7 @@
  1610.  extern int  updatecount;
  1611.  extern int  workgroup_count;
  1612.  
  1613. -/* what server type are we currently */
  1614. -
  1615. -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
  1616. +extern struct in_addr ipgrp;
  1617.  
  1618.  /****************************************************************************
  1619.    send a announce request to the local net
  1620. @@ -72,12 +70,16 @@
  1621.    CVAL(p,0) = ANN_AnnouncementRequest;
  1622.    p++;
  1623.  
  1624. -  CVAL(p,0) = work->token; /* flags?? XXXX probably a token*/
  1625. +  CVAL(p,0) = work->token; /* (local) unique workgroup token id */
  1626.    p++;
  1627.    StrnCpy(p,myname,16);
  1628.    strupper(p);
  1629.    p = skip_string(p,1);
  1630.    
  1631. +  /* XXXX note: if we sent the announcement request to 0x1d instead
  1632. +     of 0x1e, then we could get the master browser to announce to
  1633. +     us instead of the members of the workgroup. wha-hey! */
  1634. +
  1635.    send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  1636.                myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
  1637.  }
  1638. @@ -109,8 +111,32 @@
  1639.                myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
  1640.  }
  1641.  
  1642. +
  1643. +/****************************************************************************
  1644. +  find a server responsible for a workgroup, and sync browse lists
  1645. +  control ends up back here via response_name_query.
  1646. +  **************************************************************************/
  1647. +void sync_server(enum state_type state, char *serv_name, char *work_name, 
  1648. +         int name_type,
  1649. +         struct in_addr ip)
  1650. +{                     
  1651. +  add_browser_entry(serv_name, name_type, work_name, 0, ip);
  1652. +
  1653. +  if (state == NAME_STATUS_PDC_SRV_CHK)
  1654. +  {
  1655. +    /* announce ourselves as a master browser to serv_name */
  1656. +    do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
  1657. +              0x20, 0, ip);
  1658. +  }
  1659. +}
  1660. +
  1661. +
  1662.  /****************************************************************************
  1663.    construct a host announcement unicast
  1664. +
  1665. +  this function should not be used heavily, and only when we are _not_
  1666. +  a master browser and _not_ a primary domain controller.
  1667. +
  1668.    **************************************************************************/
  1669.  void announce_backup(void)
  1670.  {
  1671. @@ -120,11 +146,19 @@
  1672.    char *p;
  1673.    struct subnet_record *d1;
  1674.    int tok;
  1675. +  static uint32 id_count = 0;
  1676.    
  1677.    if (!lastrun) lastrun = t;
  1678. -  if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60) return;
  1679. +#if 1
  1680. +  if (t < lastrun + 1 * 60)
  1681. +#else
  1682. +  if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60)
  1683. +#endif
  1684. +    return;
  1685.    lastrun = t;
  1686.    
  1687. +  DEBUG(4,("checking backups...\n"));
  1688. +
  1689.    for (tok = 0; tok <= workgroup_count; tok++)
  1690.      {
  1691.        for (d1 = subnetlist; d1; d1 = d1->next)
  1692. @@ -139,18 +173,11 @@
  1693.        
  1694.        if (!work) continue;
  1695.  
  1696. +      if (AM_MASTER(work) && AM_DOMCTL(work)) continue;
  1697. +
  1698.        /* found one: announce it across all domains */
  1699.        for (d = subnetlist; d; d = d->next)
  1700.          {
  1701. -          int type=0;
  1702. -
  1703. -          if (AM_DOMCTL(work)) {
  1704. -        type = 0x1b;
  1705. -          } else if (AM_MASTER(work)) {
  1706. -        type = 0x1d;
  1707. -          } else {
  1708. -        continue;
  1709. -          }
  1710.            
  1711.            DEBUG(2,("sending announce backup %s workgroup %s(%d)\n",
  1712.                 inet_ntoa(d->bcast_ip),work->work_group,
  1713. @@ -158,20 +185,42 @@
  1714.            
  1715.            bzero(outbuf,sizeof(outbuf));
  1716.            p = outbuf;
  1717. +
  1718.            CVAL(p,0) = ANN_GetBackupListReq;
  1719. -          p++;
  1720. -          
  1721. -          CVAL(p,0) = 1; /* count? */
  1722. -          SIVAL(p,1,work->token); /* workgroup unique key index */
  1723. -          p += 5;
  1724. -          p++;
  1725. +          CVAL(p,1) = work->token; /* workgroup unique key index */
  1726. +          SIVAL(p,2,++id_count); /* unique count. not that we use it! */
  1727. +
  1728. +          p += 6;
  1729.            
  1730. -          send_mailslot_reply(BROWSE_MAILSLOT,
  1731. +          debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
  1732. +
  1733. +          if (!AM_DOMCTL(work))
  1734. +          {
  1735. +            /* only ask for a list of backup domain controllers
  1736. +               if we are not a domain controller ourselves */
  1737. +            
  1738. +              send_mailslot_reply(BROWSE_MAILSLOT,
  1739.                    ClientDGRAM,outbuf,
  1740.                    PTR_DIFF(p,outbuf),
  1741.                    myname, work->work_group,
  1742. -                  0x0,type,d->bcast_ip,
  1743. +                  0x0,0x1b,d->bcast_ip,
  1744.                    *iface_ip(d->bcast_ip));
  1745. +          }
  1746. +
  1747. +          debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
  1748. +
  1749. +          if (!AM_MASTER(work))
  1750. +          {
  1751. +            /* only ask for a list of master browsers if we
  1752. +               are not a master browser ourselves */
  1753. +
  1754. +              send_mailslot_reply(BROWSE_MAILSLOT,
  1755. +                  ClientDGRAM,outbuf,
  1756. +                  PTR_DIFF(p,outbuf),
  1757. +                  myname, work->work_group,
  1758. +                  0x0,0x1d,d->bcast_ip,
  1759. +                  *iface_ip(d->bcast_ip));
  1760. +          }
  1761.          }
  1762.      }
  1763.      }
  1764. @@ -179,19 +228,132 @@
  1765.  
  1766.  
  1767.  /****************************************************************************
  1768. +  send a host announcement packet
  1769. +  **************************************************************************/
  1770. +static void do_announce_host(int command,
  1771. +        char *from_name, int from_type, struct in_addr from_ip,
  1772. +        char *to_name  , int to_type  , struct in_addr to_ip,
  1773. +        time_t announce_interval,
  1774. +        char *server_name, int server_type, char *server_comment)
  1775. +{
  1776. +    pstring outbuf;
  1777. +    char *p;
  1778. +
  1779. +    bzero(outbuf,sizeof(outbuf));
  1780. +    p = outbuf+1;
  1781. +
  1782. +    /* command type */
  1783. +    CVAL(outbuf,0) = command;
  1784. +
  1785. +    /* announcement parameters */
  1786. +    CVAL(p,0) = updatecount;
  1787. +    SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
  1788. +
  1789. +    StrnCpy(p+5,server_name,16);
  1790. +    strupper(p+5);
  1791. +
  1792. +    CVAL(p,21) = 0x02; /* major version */
  1793. +    CVAL(p,22) = 0x02; /* minor version */
  1794. +
  1795. +    SIVAL(p,23,server_type);
  1796. +    SSVAL(p,27,0x010f); /* browse version: got from NT/AS 4.00 */
  1797. +    SSVAL(p,29,0xaa55); /* browse signature */
  1798. +
  1799. +    strcpy(p+31,server_comment);
  1800. +    p += 31;
  1801. +    p = skip_string(p,1);
  1802. +
  1803. +    debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
  1804. +
  1805. +    /* send the announcement */
  1806. +    send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
  1807. +                      PTR_DIFF(p,outbuf),
  1808. +                      from_name, to_name,
  1809. +                      from_type, to_type,
  1810. +                      to_ip, from_ip);
  1811. +}
  1812. +
  1813. +
  1814. +/****************************************************************************
  1815. +  remove all samba's server entries
  1816. +  ****************************************************************************/
  1817. +void remove_my_servers(void)
  1818. +{
  1819. +    struct subnet_record *d; 
  1820. +    for (d = subnetlist; d; d = d->next)
  1821. +    {
  1822. +        struct work_record *work;
  1823. +        for (work = d->workgrouplist; work; work = work->next)
  1824. +        {
  1825. +            struct server_record *s;
  1826. +            for (s = work->serverlist; s; s = s->next)
  1827. +            {
  1828. +                if (!strequal(myname,s->serv.name)) continue;
  1829. +                announce_server(d, work, s->serv.name, s->serv.comment, 0, 0);
  1830. +            }
  1831. +        }
  1832. +    }
  1833. +}
  1834. +
  1835. +
  1836. +/****************************************************************************
  1837. +  announce a server entry
  1838. +  ****************************************************************************/
  1839. +void announce_server(struct subnet_record *d, struct work_record *work,
  1840. +                    char *name, char *comment, time_t ttl, int server_type)
  1841. +{
  1842. +    uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX;
  1843. +
  1844. +    if (AM_MASTER(work))
  1845. +    {
  1846. +        DEBUG(3,("sending local master announce to %s for %s(1e)\n",
  1847. +                        inet_ntoa(d->bcast_ip),work->work_group));
  1848. +
  1849. +        do_announce_host(ANN_LocalMasterAnnouncement,
  1850. +                        name            , 0x00, d->myip,
  1851. +                        work->work_group, 0x1e, d->bcast_ip,
  1852. +                        ttl*1000,
  1853. +                        name, server_type, comment);
  1854. +
  1855. +        DEBUG(3,("sending domain announce to %s for %s\n",
  1856. +                        inet_ntoa(d->bcast_ip),work->work_group));
  1857. +
  1858. +        /* XXXX should we do a domain-announce-kill? */
  1859. +        if (server_type != 0)
  1860. +        {
  1861. +            if (AM_DOMCTL(work)) {
  1862. +                domain_type |= SV_TYPE_DOMAIN_CTRL;
  1863. +            }
  1864. +            do_announce_host(ANN_DomainAnnouncement,
  1865. +                        name    , 0x00, d->myip,
  1866. +                        MSBROWSE, 0x01, d->bcast_ip,
  1867. +                        ttl*1000,
  1868. +                        work->work_group, server_type ? domain_type : 0,
  1869. +                        comment);
  1870. +        }
  1871. +    }
  1872. +    else
  1873. +    {
  1874. +        DEBUG(3,("sending host announce to %s for %s(1d)\n",
  1875. +                        inet_ntoa(d->bcast_ip),work->work_group));
  1876. +
  1877. +        do_announce_host(ANN_HostAnnouncement,
  1878. +                        name            , 0x00, d->myip,
  1879. +                        work->work_group, 0x1d, d->bcast_ip,
  1880. +                        ttl*1000,
  1881. +                        name, server_type, comment);
  1882. +    }
  1883. +}
  1884. +
  1885. +/****************************************************************************
  1886.    construct a host announcement unicast
  1887.    **************************************************************************/
  1888.  void announce_host(void)
  1889.  {
  1890.    time_t t = time(NULL);
  1891. -  pstring outbuf;
  1892. -  char *p;
  1893. -  char *namep;
  1894. -  char *stypep;
  1895. -  char *commentp;
  1896. +  struct subnet_record *d;
  1897.    pstring comment;
  1898.    char *my_name;
  1899. -  struct subnet_record *d;
  1900.  
  1901.    StrnCpy(comment, *ServerComment ? ServerComment : "NoComment", 43);
  1902.  
  1903. @@ -201,8 +363,7 @@
  1904.      {
  1905.        struct work_record *work;
  1906.        
  1907. -      if (!d->my_interface)
  1908. -    continue;
  1909. +      if (ip_equal(d->bcast_ip, ipgrp)) continue;
  1910.  
  1911.        for (work = d->workgrouplist; work; work = work->next)
  1912.      {
  1913. @@ -210,11 +371,16 @@
  1914.        struct server_record *s;
  1915.        BOOL announce = False;
  1916.        
  1917. +      /* must work on the code that does announcements at up to
  1918. +         30 seconds later if a master browser sends us a request
  1919. +         announce.
  1920. +       */
  1921. +
  1922.        if (work->needannounce) {
  1923.          /* drop back to a max 3 minute announce - this is to prevent a
  1924.             single lost packet from stuffing things up for too long */
  1925. -        work->announce_interval = MIN(work->announce_interval, 
  1926. -                      CHECK_TIME_MIN_HOST_ANNCE*60);
  1927. +        work->announce_interval = MIN(work->announce_interval,
  1928. +                        CHECK_TIME_MIN_HOST_ANNCE*60);
  1929.          work->lastannounce_time = t - (work->announce_interval+1);
  1930.        }
  1931.        
  1932. @@ -242,85 +408,18 @@
  1933.        }
  1934.        
  1935.        if (announce)
  1936. -        {
  1937. -          bzero(outbuf,sizeof(outbuf));
  1938. -          p = outbuf+1;
  1939. -          
  1940. -          CVAL(p,0) = updatecount;
  1941. -          /* ms - despite the spec */
  1942. -          SIVAL(p,1,work->announce_interval*1000); 
  1943. -          namep = p+5;
  1944. -          StrnCpy(namep,my_name,16);
  1945. -          strupper(namep);
  1946. -          CVAL(p,21) = 2; /* major version */
  1947. -          CVAL(p,22) = 2; /* minor version */
  1948. -          stypep = p+23;
  1949. -          SIVAL(p,23,stype);
  1950. -          SSVAL(p,27,0xaa55); /* browse signature */
  1951. -          SSVAL(p,29,1); /* browse version */
  1952. -          commentp = p+31;
  1953. -          strcpy(commentp,comment);
  1954. -          p = p+31;
  1955. -          p = skip_string(p,1);
  1956. -          
  1957. -          if (d->my_interface)
  1958. -        {
  1959. -          if (AM_MASTER(work))
  1960. -            {
  1961. -              SIVAL(stypep,0,work->ServerType);
  1962. -              
  1963. -              DEBUG(2,("sending local master announce to %s for %s\n",
  1964. -                   inet_ntoa(d->bcast_ip),work->work_group));
  1965. -
  1966. -              CVAL(outbuf,0) = ANN_LocalMasterAnnouncement;
  1967. -              
  1968. -              send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
  1969. -                      PTR_DIFF(p,outbuf),
  1970. -                      my_name,work->work_group,0,
  1971. -                      0x1e,d->bcast_ip,
  1972. -                      *iface_ip(d->bcast_ip));
  1973. -              
  1974. -              DEBUG(2,("sending domain announce to %s for %s\n",
  1975. -                   inet_ntoa(d->bcast_ip),work->work_group));
  1976. -
  1977. -              CVAL(outbuf,0) = ANN_DomainAnnouncement;
  1978. -              
  1979. -              StrnCpy(namep,work->work_group,15);
  1980. -              strupper(namep);
  1981. -              StrnCpy(commentp,myname,15);
  1982. -              strupper(commentp);
  1983. -              
  1984. -              SIVAL(stypep,0,(unsigned)0x80000000);
  1985. -              p = commentp + strlen(commentp) + 1;
  1986. -              
  1987. -              send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
  1988. -                      PTR_DIFF(p,outbuf),
  1989. -                      my_name,MSBROWSE,0,0x01,d->bcast_ip,
  1990. -                      *iface_ip(d->bcast_ip));
  1991. -            }
  1992. -          else
  1993. -            {
  1994. -              DEBUG(2,("sending host announce to %s for %s\n",
  1995. -                   inet_ntoa(d->bcast_ip),work->work_group));
  1996. -
  1997. -              CVAL(outbuf,0) = ANN_HostAnnouncement;
  1998. -              
  1999. -              send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
  2000. -                      PTR_DIFF(p,outbuf),
  2001. -                      my_name,work->work_group,0,0x1d,
  2002. -                      d->bcast_ip,*iface_ip(d->bcast_ip));
  2003. -            }
  2004. -        }
  2005. -        }
  2006. +      {
  2007. +        announce_server(d,work,my_name,comment,work->announce_interval,stype);
  2008. +      }
  2009.        
  2010.        if (work->needannounce)
  2011. -        {
  2012. +      {
  2013.            work->needannounce = False;
  2014.            break;
  2015.            /* sorry: can't do too many announces. do some more later */
  2016. -        }
  2017. +      }
  2018.      }
  2019. -    }
  2020. +  }
  2021.  }
  2022.  
  2023.  
  2024. @@ -332,7 +431,7 @@
  2025.    least 15 minutes.
  2026.    
  2027.    this actually gets done in search_and_sync_workgroups() via the
  2028. -  MASTER_SERVER_CHECK command, if there is a response from the
  2029. +  NAME_QUERY_PDC_SRV_CHK command, if there is a response from the
  2030.    name query initiated here.  see response_name_query()
  2031.    **************************************************************************/
  2032.  void announce_master(void)
  2033. @@ -342,8 +441,9 @@
  2034.    time_t t = time(NULL);
  2035.    BOOL am_master = False; /* are we a master of some sort? :-) */
  2036.  
  2037. -  if (last && (t-last < CHECK_TIME_MST_ANNOUNCE * 60)) 
  2038. -    return; 
  2039. +  if (!last) last = t;
  2040. +  if (t-last < CHECK_TIME_MST_ANNOUNCE * 60)
  2041. +    return;
  2042.  
  2043.    last = t;
  2044.  
  2045. @@ -386,20 +486,20 @@
  2046.                struct in_addr ip;
  2047.                ip = ipzero;
  2048.                
  2049. -              queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
  2050. -                         MASTER_SERVER_CHECK,
  2051. -                         work->work_group,0x1b,0,
  2052. -                         False, False, ip);
  2053. +              queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
  2054. +                         NAME_QUERY_PDC_SRV_CHK,
  2055. +                         work->work_group,0x1b,0,0,
  2056. +                         False, False, ip, ip);
  2057.              }
  2058.                else
  2059.              {
  2060.                struct subnet_record *d2;
  2061.                for (d2 = subnetlist; d2; d2 = d2->next)
  2062.                  {
  2063. -                  queue_netbios_packet(ClientNMB,NMB_QUERY,
  2064. -                           MASTER_SERVER_CHECK,
  2065. -                           work->work_group,0x1b,0,
  2066. -                           True, False, d2->bcast_ip);
  2067. +                  queue_netbios_packet(d,ClientNMB,NMB_QUERY,
  2068. +                           NAME_QUERY_PDC_SRV_CHK,
  2069. +                           work->work_group,0x1b,0,0,
  2070. +                           True, False, d2->bcast_ip, d2->bcast_ip);
  2071.                  }
  2072.              }
  2073.              }
  2074. @@ -431,9 +531,9 @@
  2075.            /* check the existence of a pdc for this workgroup, and if
  2076.           one exists at the specified ip, sync with it and announce
  2077.           ourselves as a master browser to it */
  2078. -          queue_netbios_pkt_wins(ClientNMB, NMB_QUERY,MASTER_SERVER_CHECK,
  2079. -                     work->work_group,0x1b, 0,
  2080. -                     bcast, False, ip);
  2081. +          queue_netbios_pkt_wins(d,ClientNMB, NMB_QUERY,NAME_QUERY_PDC_SRV_CHK,
  2082. +                     work->work_group,0x1b, 0, 0,
  2083. +                     bcast, False, ip, ip);
  2084.          }
  2085.      }
  2086.      }
  2087. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameannounce.doc samba-1.9.16alpha11/source/nameannounce.doc
  2088. --- samba-1.9.16alpha10/source/nameannounce.doc    Thu Jan  1 10:00:00 1970
  2089. +++ samba-1.9.16alpha11/source/nameannounce.doc    Sun Jul  7 22:35:54 1996
  2090. @@ -0,0 +1,137 @@
  2091. +this module deals with announcements: the sending of announcement requests
  2092. +and the sending of announcements either to refresh other servers' records
  2093. +or as a response to announcement requests.
  2094. +
  2095. +
  2096. +/*************************************************************************
  2097. +  announce_master()
  2098. +  *************************************************************************/
  2099. +
  2100. +this function is responsible for announcing samba as a master browser
  2101. +to all known primary domain controllers.
  2102. +
  2103. +this announcement is sent out at CHECK_TIME_MST_ANNOUNCE minute
  2104. +intervals, only if samba is a master browser on one or more of
  2105. +its local interfaces.
  2106. +
  2107. +if no domain controller has been specified (lp_domain_controller())
  2108. +samba goes through its list of servers looking for primary domain
  2109. +controllers. when it finds one (other than itself) it will either
  2110. +initiate a NAME_QUERY_PDC_SRV_CHK by broadcast or with a WINS
  2111. +server. this will result in a NAME_STATUS_PDC_SRV_CHK, which
  2112. +will result in a sync browse list and an announcement
  2113. +ANN_MasterAnnounce being sent (see sync_server()).
  2114. +
  2115. +if a domain controller has been specified, samba will search for
  2116. +a primary domain controller for its workgroup (either by directed
  2117. +packet or by broadcast if it cannot resolve the domain controller
  2118. +name using DNS), which results in the same action as listed above.
  2119. +
  2120. +
  2121. +/*************************************************************************
  2122. +  announce_host()
  2123. +  *************************************************************************/
  2124. +
  2125. +this complex-looking function is responsible for announcing samba's
  2126. +existence to other servers by broadcast. the actual announcement
  2127. +is carried out by announce_server().
  2128. +
  2129. +the time period between samba's announcement will stretch from one
  2130. +minute to twelve minutes by one minute. if samba has received an
  2131. +announce request from a master browser, then it should answer at
  2132. +any random interval between zero and thirty seconds after the
  2133. +request is received. this is to ensure that the master browser
  2134. +does not get overloaded with responses!
  2135. +
  2136. +
  2137. +/*************************************************************************
  2138. +  announce_server()
  2139. +  *************************************************************************/
  2140. +
  2141. +this function is responsible for sending announcement packets.
  2142. +these packets are received by other servers, which will then
  2143. +update their records accordingly: what services we have, our
  2144. +name, our comment field and our time to live (to name a few).
  2145. +
  2146. +if we are a master browser, then using do_announce_host() we
  2147. +must send an announcement notifying members of that workgroup
  2148. +that we are their master browser, and another announcement
  2149. +indicating to all backup browsers and master browsers that
  2150. +we are a master browser.
  2151. +
  2152. +(note: if another master browser receives this announcement
  2153. +and thinks that it is also the master browser for this
  2154. +workgroup, it stops being a master browser and forces an
  2155. +election).
  2156. +
  2157. +if we are not a master browser, then we send an announcement
  2158. +notifying the master browser that we are a member of its
  2159. +workgroup.
  2160. +
  2161. +
  2162. +/*************************************************************************
  2163. +  remove_my_servers()
  2164. +  *************************************************************************/
  2165. +
  2166. +this function is responsible for informing other servers that
  2167. +samba is about to go down. it announces, on all subnets, that
  2168. +samba's time to live is zero and that it has no services.
  2169. +
  2170. +
  2171. +/*************************************************************************
  2172. +  do_announce_host()
  2173. +  *************************************************************************/
  2174. +
  2175. +this function is responsible for sending out an announcement
  2176. +MAILSLOT browse packet. it contains information such as the
  2177. +time to live, name of the server, services that the server
  2178. +offers etc.
  2179. +
  2180. +the format of this MAILSLOT browse packet is described in
  2181. +draft-heizer-cifs-v1-spec-00.txt 3.9.50.4.1 page 165-6.
  2182. +
  2183. +
  2184. +/*************************************************************************
  2185. +  announce_backup()
  2186. +  *************************************************************************/
  2187. +
  2188. +this function is responsible for getting master browsers and domain
  2189. +controllers to send us lists of backup servers. this is done by
  2190. +sending an ANN_GetBackupListReq browse mailslot.
  2191. +
  2192. +the master browser, or primary domain controller, should respond 
  2193. +with an ANN_GetBackupListResp browse mailslot containing the list
  2194. +of backup servers.
  2195. +
  2196. +
  2197. +/*************************************************************************
  2198. +  sync_server()
  2199. +  *************************************************************************/
  2200. +
  2201. +this function is responsible for initiating a sync browse list
  2202. +sequence and, if necessary, carrying out an ANN_MasterAnnouncement
  2203. +to the primary domain controller (that we are also sync'ing
  2204. +browse lists with).
  2205. +
  2206. +see nameservresp.c:response_name_status_check().
  2207. +
  2208. +
  2209. +/*************************************************************************
  2210. +  announce_request()
  2211. +  *************************************************************************/
  2212. +
  2213. +this function is responsible for sending an announcement request to
  2214. +another server. this server should respond with an announcement.
  2215. +
  2216. +if the announce request is sent to WORKGROUP(0x1e) then members of
  2217. +the workgroup will respond (with ANN_HostAnnounce packets)
  2218. +
  2219. +if the announce request is sent to WORKGROUP(0x1d) then the master
  2220. +browser of the workgroup should respond (ANN_LocalMasterAnnounce).
  2221. +this is untested.
  2222. +
  2223. +if the announce request is sent to ^1^2__MSBROWSE__^2(0x1) then
  2224. +(and this is pure speculation), all backup browsers and master
  2225. +browsers should respond with ANN_DomainAnnounce packets.
  2226. +this is untested.
  2227. +
  2228. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namebrowse.c samba-1.9.16alpha11/source/namebrowse.c
  2229. --- samba-1.9.16alpha10/source/namebrowse.c    Thu Jan  1 10:00:00 1970
  2230. +++ samba-1.9.16alpha11/source/namebrowse.c    Sun Jul  7 22:35:54 1996
  2231. @@ -0,0 +1,217 @@
  2232. +/* 
  2233. +   Unix SMB/Netbios implementation.
  2234. +   Version 1.9.
  2235. +   NBT netbios routines and daemon - version 2
  2236. +   Copyright (C) Andrew Tridgell 1994-1995
  2237. +   
  2238. +   This program is free software; you can redistribute it and/or modify
  2239. +   it under the terms of the GNU General Public License as published by
  2240. +   the Free Software Foundation; either version 2 of the License, or
  2241. +   (at your option) any later version.
  2242. +   
  2243. +   This program is distributed in the hope that it will be useful,
  2244. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  2245. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2246. +   GNU General Public License for more details.
  2247. +   
  2248. +   You should have received a copy of the GNU General Public License
  2249. +   along with this program; if not, write to the Free Software
  2250. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2251. +   
  2252. +   Revision History:
  2253. +
  2254. +   14 jan 96: lkcl@pires.co.uk
  2255. +   added multiple workgroup domain master support
  2256. +
  2257. +*/
  2258. +
  2259. +#include "includes.h"
  2260. +#include "smb.h"
  2261. +
  2262. +extern int ClientNMB;
  2263. +
  2264. +extern int DEBUGLEVEL;
  2265. +
  2266. +/* this is our browse master/backup cache database */
  2267. +static struct browse_cache_record *browserlist = NULL;
  2268. +
  2269. +
  2270. +/***************************************************************************
  2271. +  add a browser into the list
  2272. +  **************************************************************************/
  2273. +static void add_browse_cache(struct browse_cache_record *b)
  2274. +{
  2275. +  struct browse_cache_record *b2;
  2276. +
  2277. +  if (!browserlist)
  2278. +    {
  2279. +      browserlist = b;
  2280. +      b->prev = NULL;
  2281. +      b->next = NULL;
  2282. +      return;
  2283. +    }
  2284. +  
  2285. +  for (b2 = browserlist; b2->next; b2 = b2->next) ;
  2286. +  
  2287. +  b2->next = b;
  2288. +  b->next = NULL;
  2289. +  b->prev = b2;
  2290. +}
  2291. +
  2292. +
  2293. +/*******************************************************************
  2294. +  remove old browse entries
  2295. +  ******************************************************************/
  2296. +void expire_browse_cache(time_t t)
  2297. +{
  2298. +  struct browse_cache_record *b;
  2299. +  struct browse_cache_record *nextb;
  2300. +  
  2301. +  /* expire old entries in the serverlist */
  2302. +  for (b = browserlist; b; b = nextb)
  2303. +    {
  2304. +      if (b->synced && b->sync_time < t)
  2305. +    {
  2306. +      DEBUG(3,("Removing dead cached browser %s\n",b->name));
  2307. +      nextb = b->next;
  2308. +      
  2309. +      if (b->prev) b->prev->next = b->next;
  2310. +      if (b->next) b->next->prev = b->prev;
  2311. +      
  2312. +      if (browserlist == b) browserlist = b->next; 
  2313. +      
  2314. +      free(b);
  2315. +    }
  2316. +      else
  2317. +    {
  2318. +      nextb = b->next;
  2319. +    }
  2320. +    }
  2321. +}
  2322. +
  2323. +
  2324. +/****************************************************************************
  2325. +  add a browser entry
  2326. +  ****************************************************************************/
  2327. +struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
  2328. +                          time_t ttl, struct in_addr ip)
  2329. +{
  2330. +  BOOL newentry=False;
  2331. +  
  2332. +  struct browse_cache_record *b;
  2333. +
  2334. +  /* search for the entry: if it's already in the cache, update that entry */
  2335. +  for (b = browserlist; b; b = b->next)
  2336. +    {
  2337. +      if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break;
  2338. +    }
  2339. +  
  2340. +  if (b && b->synced)
  2341. +    {
  2342. +      /* entries get left in the cache for a while. this stops sync'ing too
  2343. +     often if the network is large */
  2344. +      DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
  2345. +        b->name, b->group, inet_ntoa(b->ip), b->sync_time));
  2346. +      return NULL;
  2347. +    }
  2348. +  
  2349. +  if (!b)
  2350. +    {
  2351. +      newentry = True;
  2352. +      b = (struct browse_cache_record *)malloc(sizeof(*b));
  2353. +      
  2354. +      if (!b) return(NULL);
  2355. +      
  2356. +      bzero((char *)b,sizeof(*b));
  2357. +    }
  2358. +  
  2359. +  /* update the entry */
  2360. +  ttl = time(NULL)+ttl;
  2361. +  
  2362. +  StrnCpy(b->name ,name,sizeof(b->name )-1);
  2363. +  StrnCpy(b->group,wg  ,sizeof(b->group)-1);
  2364. +  strupper(b->name);
  2365. +  strupper(b->group);
  2366. +  
  2367. +  b->ip     = ip;
  2368. +  b->type   = type;
  2369. +  
  2370. +  if (newentry || ttl < b->sync_time) 
  2371. +    b->sync_time = ttl;
  2372. +  
  2373. +  if (newentry)
  2374. +    {
  2375. +      b->synced = False;
  2376. +      add_browse_cache(b);
  2377. +      
  2378. +      DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
  2379. +           wg, name, type, inet_ntoa(ip),ttl));
  2380. +    }
  2381. +  else
  2382. +    {
  2383. +      DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
  2384. +           wg, name, type, inet_ntoa(ip),ttl));
  2385. +    }
  2386. +  
  2387. +  return(b);
  2388. +}
  2389. +
  2390. +
  2391. +/****************************************************************************
  2392. +find a server responsible for a workgroup, and sync browse lists
  2393. +**************************************************************************/
  2394. +static void start_sync_browse_entry(struct browse_cache_record *b)
  2395. +{                     
  2396. +  struct subnet_record *d;
  2397. +  struct work_record *work;
  2398. +
  2399. +  if (!(d = find_subnet(b->ip))) return;
  2400. +
  2401. +  if (!(work = find_workgroupstruct(d, b->group, False))) return;
  2402. +
  2403. +  /* only sync if we are the master */
  2404. +  if (AM_MASTER(work)) {
  2405. +
  2406. +      /* first check whether the group we intend to sync with exists. if it
  2407. +         doesn't, the server must have died. o dear. */
  2408. +
  2409. +      /* see response_netbios_packet() or expire_netbios_response_entries() */
  2410. +      queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_SYNC,
  2411. +                       b->group,0x20,0,0,
  2412. +                       False,False,b->ip,b->ip);
  2413. +  }
  2414. +
  2415. +  b->synced = True;
  2416. +}
  2417. +
  2418. +
  2419. +/****************************************************************************
  2420. +  search through browser list for an entry to sync with
  2421. +  **************************************************************************/
  2422. +void do_browser_lists(void)
  2423. +{
  2424. +  struct browse_cache_record *b;
  2425. +  static time_t last = 0;
  2426. +  time_t t = time(NULL);
  2427. +  
  2428. +  if (t-last < 20) return; /* don't do too many of these at once! */
  2429. +                           /* XXXX equally this period should not be too long
  2430. +                              the server may die in the intervening gap */
  2431. +  
  2432. +  last = t;
  2433. +  
  2434. +  /* pick any entry in the list, preferably one whose time is up */
  2435. +  for (b = browserlist; b && b->next; b = b->next)
  2436. +    {
  2437. +      if (b->sync_time < t && b->synced == False) break;
  2438. +    }
  2439. +  
  2440. +  if (b && !b->synced)
  2441. +  {
  2442. +    /* sync with the selected entry then remove some dead entries */
  2443. +    start_sync_browse_entry(b);
  2444. +    expire_browse_cache(t - 60);
  2445. +  }
  2446. +
  2447. +}
  2448. +
  2449. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namebrowse.doc samba-1.9.16alpha11/source/namebrowse.doc
  2450. --- samba-1.9.16alpha10/source/namebrowse.doc    Thu Jan  1 10:00:00 1970
  2451. +++ samba-1.9.16alpha11/source/namebrowse.doc    Sun Jul  7 22:35:54 1996
  2452. @@ -0,0 +1,69 @@
  2453. +this module deals with queueing servers that samba must sync browse
  2454. +lists with. it will always issue a name query immediately before
  2455. +actually carrying out the NetServerEnum call, to ensure that time
  2456. +is not wasted by a remote server's failure.
  2457. +
  2458. +this module was created to minimise the amount of NetServerEnum calls
  2459. +that samba may be asked to perform, by maintaining the name of a server
  2460. +for up to a minute after the NetServerEnum call was issued, and
  2461. +disallowing further NetServerEnum calls to this remote server until
  2462. +the entry is removed.
  2463. +
  2464. +samba can ask for a NetServerEnum call to be issued to grab a remote
  2465. +server's list of servers and workgroups either in its capacity as
  2466. +a primary domain controller (domain master browser), as a local
  2467. +master browser.
  2468. +
  2469. +samba does not deal with becoming a backup master browser properly
  2470. +at present.
  2471. +
  2472. +
  2473. +/*************************************************************************
  2474. +  do_browser_lists()
  2475. +  *************************************************************************/
  2476. +
  2477. +this function is responsible for finding an appropriate entry in the
  2478. +sync browser cache, initiating a name query (which results in a
  2479. +NetServerEnum call if there is a positive response), and then
  2480. +removing all entries that have been actioned and have been around
  2481. +for over a minute.
  2482. +
  2483. +
  2484. +/*************************************************************************
  2485. +  start_sync_browse_entry()
  2486. +  *************************************************************************/
  2487. +
  2488. +this function is responsible for initiating a name query. if a
  2489. +positive response is received, then this will result in a
  2490. +NetServerEnum api call.
  2491. +
  2492. +samba will only initiate this process if it is a master browser
  2493. +for this workgroup.
  2494. +
  2495. +
  2496. +/*************************************************************************
  2497. +  add_browser_entry()
  2498. +  *************************************************************************/
  2499. +
  2500. +this function is responsible for adding a browser into the list of
  2501. +servers to sync browse lists with. if the server entry has already
  2502. +been added and syncing browse lists has already been initiated, it
  2503. +will not be added again.
  2504. +
  2505. +
  2506. +/*************************************************************************
  2507. +  expire_browse_cache()
  2508. +  *************************************************************************/
  2509. +
  2510. +this function is responsible for removing entries that have had the
  2511. +sync browse list initiated (whether that succeeded or not is beyond
  2512. +this function's scope) and have been in the cache for a while.
  2513. +
  2514. +
  2515. +/*************************************************************************
  2516. +  add_browse_entry()
  2517. +  *************************************************************************/
  2518. +
  2519. +this function is responsible for adding a new entry into the list
  2520. +of servers to sync browse lists with at some point in the near future.
  2521. +
  2522. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedb.c samba-1.9.16alpha11/source/namedb.c
  2523. --- samba-1.9.16alpha10/source/namedb.c    Mon Jun 10 15:18:56 1996
  2524. +++ samba-1.9.16alpha11/source/namedb.c    Thu Jan  1 10:00:00 1970
  2525. @@ -1,720 +0,0 @@
  2526. -/* 
  2527. -   Unix SMB/Netbios implementation.
  2528. -   Version 1.9.
  2529. -   NBT netbios routines and daemon - version 2
  2530. -   Copyright (C) Andrew Tridgell 1994-1995
  2531. -   
  2532. -   This program is free software; you can redistribute it and/or modify
  2533. -   it under the terms of the GNU General Public License as published by
  2534. -   the Free Software Foundation; either version 2 of the License, or
  2535. -   (at your option) any later version.
  2536. -   
  2537. -   This program is distributed in the hope that it will be useful,
  2538. -   but WITHOUT ANY WARRANTY; without even the implied warranty of
  2539. -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2540. -   GNU General Public License for more details.
  2541. -   
  2542. -   You should have received a copy of the GNU General Public License
  2543. -   along with this program; if not, write to the Free Software
  2544. -   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2545. -   
  2546. -   Revision History:
  2547. -
  2548. -   14 jan 96: lkcl@pires.co.uk
  2549. -   added multiple workgroup domain master support
  2550. -
  2551. -*/
  2552. -
  2553. -#include "includes.h"
  2554. -#include "smb.h"
  2555. -
  2556. -extern int ClientNMB;
  2557. -extern int ClientDGRAM;
  2558. -
  2559. -extern int DEBUGLEVEL;
  2560. -
  2561. -extern time_t StartupTime;
  2562. -extern pstring myname;
  2563. -extern pstring scope;
  2564. -
  2565. -extern struct in_addr ipgrp;
  2566. -
  2567. -/* this is our browse master/backup cache database */
  2568. -struct browse_cache_record *browserlist = NULL;
  2569. -
  2570. -/* this is our domain/workgroup/server database */
  2571. -struct subnet_record *subnetlist = NULL;
  2572. -
  2573. -static BOOL updatedlists = True;
  2574. -int  updatecount=0;
  2575. -
  2576. -int workgroup_count = 0; /* unique index key: one for each workgroup */
  2577. -
  2578. -/* what server type are we currently */
  2579. -
  2580. -#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
  2581. -            SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
  2582. -            SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
  2583. -
  2584. -
  2585. -/****************************************************************************
  2586. -  add a workgroup into the domain list
  2587. -  **************************************************************************/
  2588. -static void add_workgroup(struct work_record *work, struct subnet_record *d)
  2589. -{
  2590. -  struct work_record *w2;
  2591. -
  2592. -  if (!work || !d) return;
  2593. -
  2594. -  if (!d->workgrouplist)
  2595. -    {
  2596. -      d->workgrouplist = work;
  2597. -      work->prev = NULL;
  2598. -      work->next = NULL;
  2599. -      return;
  2600. -    }
  2601. -  
  2602. -  for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
  2603. -  
  2604. -  w2->next = work;
  2605. -  work->next = NULL;
  2606. -  work->prev = w2;
  2607. -}
  2608. -
  2609. -
  2610. -/****************************************************************************
  2611. -  create a blank workgroup 
  2612. -  **************************************************************************/
  2613. -static struct work_record *make_workgroup(char *name)
  2614. -{
  2615. -  struct work_record *work;
  2616. -  struct subnet_record *d;
  2617. -  int t = -1;
  2618. -  
  2619. -  if (!name || !name[0]) return NULL;
  2620. -  
  2621. -  work = (struct work_record *)malloc(sizeof(*work));
  2622. -  if (!work) return(NULL);
  2623. -  
  2624. -  StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
  2625. -  work->serverlist = NULL;
  2626. -  
  2627. -  work->ServerType = DFLT_SERVER_TYPE;
  2628. -  work->RunningElection = False;
  2629. -  work->ElectionCount = 0;
  2630. -  work->needelection = False;
  2631. -  work->needannounce = True;
  2632. -  
  2633. -  /* make sure all token representations of workgroups are unique */
  2634. -  
  2635. -  for (d = subnetlist; d && t == -1; d = d->next)
  2636. -    {
  2637. -      struct work_record *w;
  2638. -      for (w = d->workgrouplist; w && t == -1; w = w->next)
  2639. -    {
  2640. -      if (strequal(w->work_group, work->work_group)) t = w->token;
  2641. -    }
  2642. -    }
  2643. -  
  2644. -  if (t == -1)
  2645. -    {
  2646. -      work->token = ++workgroup_count;
  2647. -    }
  2648. -  else
  2649. -    {
  2650. -      work->token = t;
  2651. -    }
  2652. -  
  2653. -  
  2654. -  /* WfWg  uses 01040b01 */
  2655. -  /* Win95 uses 01041501 */
  2656. -  /* NTAS  uses ???????? */
  2657. -  work->ElectionCriterion  = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8); 
  2658. -  work->ElectionCriterion |= (lp_os_level() << 24);
  2659. -  if (lp_domain_master()) {
  2660. -    work->ElectionCriterion |= 0x80;
  2661. -  }
  2662. -  
  2663. -  return work;
  2664. -}
  2665. -
  2666. -
  2667. -/*******************************************************************
  2668. -  expire old servers in the serverlist
  2669. -  time of -1 indicates everybody dies
  2670. -  ******************************************************************/
  2671. -static void remove_old_servers(struct work_record *work, time_t t)
  2672. -{
  2673. -  struct server_record *s;
  2674. -  struct server_record *nexts;
  2675. -  
  2676. -  /* expire old entries in the serverlist */
  2677. -  for (s = work->serverlist; s; s = nexts)
  2678. -    {
  2679. -      if (t == -1 || (s->death_time && s->death_time < t))
  2680. -    {
  2681. -      DEBUG(3,("Removing dead server %s\n",s->serv.name));
  2682. -      updatedlists = True;
  2683. -      nexts = s->next;
  2684. -      
  2685. -      if (s->prev) s->prev->next = s->next;
  2686. -      if (s->next) s->next->prev = s->prev;
  2687. -      
  2688. -      if (work->serverlist == s) 
  2689. -        work->serverlist = s->next; 
  2690. -
  2691. -      free(s);
  2692. -    }
  2693. -      else
  2694. -    {
  2695. -      nexts = s->next;
  2696. -    }
  2697. -    }
  2698. -}
  2699. -
  2700. -
  2701. -/*******************************************************************
  2702. -  remove workgroups
  2703. -  ******************************************************************/
  2704. -struct work_record *remove_workgroup(struct subnet_record *d, 
  2705. -                     struct work_record *work)
  2706. -{
  2707. -  struct work_record *ret_work = NULL;
  2708. -  
  2709. -  if (!d || !work) return NULL;
  2710. -  
  2711. -  DEBUG(3,("Removing old workgroup %s\n", work->work_group));
  2712. -  
  2713. -  remove_old_servers(work, -1);
  2714. -  
  2715. -  ret_work = work->next;
  2716. -  
  2717. -  if (work->prev) work->prev->next = work->next;
  2718. -  if (work->next) work->next->prev = work->prev;
  2719. -  
  2720. -  if (d->workgrouplist == work) d->workgrouplist = work->next; 
  2721. -  
  2722. -  free(work);
  2723. -  
  2724. -  return ret_work;
  2725. -}
  2726. -
  2727. -
  2728. -/****************************************************************************
  2729. -  add a domain into the list
  2730. -  **************************************************************************/
  2731. -static void add_subnet(struct subnet_record *d)
  2732. -{
  2733. -  struct subnet_record *d2;
  2734. -
  2735. -  if (!subnetlist)
  2736. -  {
  2737. -    subnetlist = d;
  2738. -    d->prev = NULL;
  2739. -    d->next = NULL;
  2740. -    return;
  2741. -  }
  2742. -
  2743. -  for (d2 = subnetlist; d2->next; d2 = d2->next);
  2744. -
  2745. -  d2->next = d;
  2746. -  d->next = NULL;
  2747. -  d->prev = d2;
  2748. -}
  2749. -
  2750. -/***************************************************************************
  2751. -  add a browser into the list
  2752. -  **************************************************************************/
  2753. -static void add_browse_cache(struct browse_cache_record *b)
  2754. -{
  2755. -  struct browse_cache_record *b2;
  2756. -
  2757. -  if (!browserlist)
  2758. -    {
  2759. -      browserlist = b;
  2760. -      b->prev = NULL;
  2761. -      b->next = NULL;
  2762. -      return;
  2763. -    }
  2764. -  
  2765. -  for (b2 = browserlist; b2->next; b2 = b2->next) ;
  2766. -  
  2767. -  b2->next = b;
  2768. -  b->next = NULL;
  2769. -  b->prev = b2;
  2770. -}
  2771. -
  2772. -
  2773. -/***************************************************************************
  2774. -  add a server into the list
  2775. -  **************************************************************************/
  2776. -static void add_server(struct work_record *work,struct server_record *s)
  2777. -{
  2778. -  struct server_record *s2;
  2779. -
  2780. -  if (!work->serverlist) {
  2781. -    work->serverlist = s;
  2782. -    s->prev = NULL;
  2783. -    s->next = NULL;
  2784. -    return;
  2785. -  }
  2786. -
  2787. -  for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
  2788. -
  2789. -  s2->next = s;
  2790. -  s->next = NULL;
  2791. -  s->prev = s2;
  2792. -}
  2793. -
  2794. -
  2795. -/*******************************************************************
  2796. -  remove old browse entries
  2797. -  ******************************************************************/
  2798. -void expire_browse_cache(time_t t)
  2799. -{
  2800. -  struct browse_cache_record *b;
  2801. -  struct browse_cache_record *nextb;
  2802. -  
  2803. -  /* expire old entries in the serverlist */
  2804. -  for (b = browserlist; b; b = nextb)
  2805. -    {
  2806. -      if (b->synced && b->sync_time < t)
  2807. -    {
  2808. -      DEBUG(3,("Removing dead cached browser %s\n",b->name));
  2809. -      nextb = b->next;
  2810. -      
  2811. -      if (b->prev) b->prev->next = b->next;
  2812. -      if (b->next) b->next->prev = b->prev;
  2813. -      
  2814. -      if (browserlist == b) browserlist = b->next; 
  2815. -      
  2816. -      free(b);
  2817. -    }
  2818. -      else
  2819. -    {
  2820. -      nextb = b->next;
  2821. -    }
  2822. -    }
  2823. -}
  2824. -
  2825. -
  2826. -/****************************************************************************
  2827. -  find a workgroup in the workgrouplist 
  2828. -  only create it if the domain allows it, or the parameter 'add' insists
  2829. -  that it get created/added anyway. this allows us to force entries in
  2830. -  lmhosts file to be added.
  2831. -  **************************************************************************/
  2832. -struct work_record *find_workgroupstruct(struct subnet_record *d, 
  2833. -                     fstring name, BOOL add)
  2834. -{
  2835. -  struct work_record *ret, *work;
  2836. -  
  2837. -  if (!d) return NULL;
  2838. -  
  2839. -  DEBUG(4, ("workgroup search for %s: ", name));
  2840. -  
  2841. -  if (strequal(name, "*"))
  2842. -    {
  2843. -      DEBUG(2,("add any workgroups: initiating browser search on %s\n",
  2844. -           inet_ntoa(d->bcast_ip)));
  2845. -      queue_netbios_pkt_wins(ClientNMB,NMB_QUERY, FIND_MASTER,
  2846. -                 MSBROWSE,0x1,0,
  2847. -                 True,False, d->bcast_ip);
  2848. -      return NULL;
  2849. -    }
  2850. -  
  2851. -  for (ret = d->workgrouplist; ret; ret = ret->next) {
  2852. -    if (!strcmp(ret->work_group,name)) {
  2853. -      DEBUG(4, ("found\n"));
  2854. -      return(ret);
  2855. -    }
  2856. -  }
  2857. -
  2858. -  if (!add) {
  2859. -    DEBUG(4, ("not found\n"));
  2860. -    return NULL;
  2861. -  }
  2862. -
  2863. -  DEBUG(4,("not found: creating\n"));
  2864. -  
  2865. -  if ((work = make_workgroup(name)))
  2866. -    {
  2867. -      if (lp_preferred_master() &&
  2868. -      strequal(lp_workgroup(), name) &&
  2869. -      d->my_interface)
  2870. -    {
  2871. -      DEBUG(3, ("preferred master startup for %s\n", work->work_group));
  2872. -      work->needelection = True;
  2873. -      work->ElectionCriterion |= (1<<3);
  2874. -    }
  2875. -      if (!d->my_interface)
  2876. -    {
  2877. -      work->needelection = False;
  2878. -    }
  2879. -      add_workgroup(work, d);
  2880. -      return(work);
  2881. -    }
  2882. -  return NULL;
  2883. -}
  2884. -
  2885. -/****************************************************************************
  2886. -  find a domain in the subnetlist 
  2887. -  **************************************************************************/
  2888. -struct subnet_record *find_domain(struct in_addr ip)
  2889. -{   
  2890. -  struct subnet_record *d;
  2891. -  
  2892. -  /* search through domain list for broadcast/netmask that matches
  2893. -     the source ip address */
  2894. -  
  2895. -  for (d = subnetlist; d; d = d->next)
  2896. -    {
  2897. -      if (same_net(ip, d->bcast_ip, d->mask_ip))
  2898. -    return(d);
  2899. -    }
  2900. -  
  2901. -  return (NULL);
  2902. -}
  2903. -
  2904. -
  2905. -/****************************************************************************
  2906. -  dump a copy of the workgroup/domain database
  2907. -  **************************************************************************/
  2908. -void dump_workgroups(void)
  2909. -{
  2910. -  struct subnet_record *d;
  2911. -  
  2912. -  for (d = subnetlist; d; d = d->next)
  2913. -    {
  2914. -      if (d->workgrouplist)
  2915. -    {
  2916. -      struct work_record *work;
  2917. -      
  2918. -      DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
  2919. -      DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
  2920. -      
  2921. -      for (work = d->workgrouplist; work; work = work->next)
  2922. -        {
  2923. -          DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
  2924. -          if (work->serverlist)
  2925. -        {
  2926. -          struct server_record *s;          
  2927. -          for (s = work->serverlist; s; s = s->next)
  2928. -            {
  2929. -              DEBUG(4,("\t\t%s %8x (%s)\n",
  2930. -                   s->serv.name, s->serv.type, s->serv.comment));
  2931. -            }
  2932. -        }
  2933. -        }
  2934. -    }
  2935. -    }
  2936. -}
  2937. -
  2938. -/****************************************************************************
  2939. -  create a domain entry
  2940. -  ****************************************************************************/
  2941. -static struct subnet_record *make_subnet(struct in_addr bcast_ip,
  2942. -                     struct in_addr mask)
  2943. -{
  2944. -  struct subnet_record *d;
  2945. -  d = (struct subnet_record *)malloc(sizeof(*d));
  2946. -  
  2947. -  if (!d) return(NULL);
  2948. -  
  2949. -  bzero((char *)d,sizeof(*d));
  2950. -  
  2951. -  DEBUG(4,("making subnet %s ", inet_ntoa(bcast_ip)));
  2952. -  DEBUG(4,("%s\n", inet_ntoa(mask)));
  2953. -  
  2954. -  d->bcast_ip = bcast_ip;
  2955. -  d->mask_ip  = mask;
  2956. -  d->workgrouplist = NULL;
  2957. -  d->my_interface = ismybcast(d->bcast_ip);
  2958. -
  2959. -  add_subnet(d);
  2960. -  
  2961. -  return d;
  2962. -}
  2963. -
  2964. -/****************************************************************************
  2965. -  add a domain entry. creates a workgroup, if necessary, and adds the domain
  2966. -  to the named a workgroup.
  2967. -  ****************************************************************************/
  2968. -struct subnet_record *add_subnet_entry(struct in_addr source_ip, 
  2969. -                       struct in_addr source_mask,
  2970. -                       char *name, BOOL add)
  2971. -{
  2972. -  struct subnet_record *d;
  2973. -  struct in_addr ip;
  2974. -  
  2975. -  ip = ipgrp;
  2976. -  
  2977. -  if (zero_ip(source_ip)) 
  2978. -    source_ip = *iface_bcast(source_ip);
  2979. -  
  2980. -  /* add the domain into our domain database */
  2981. -  if ((d = find_domain(source_ip)) ||
  2982. -      (d = make_subnet(source_ip, source_mask)))
  2983. -    {
  2984. -      struct work_record *w = find_workgroupstruct(d, name, add);
  2985. -      
  2986. -      if (!w) return NULL;
  2987. -
  2988. -      /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
  2989. -     or register with WINS server, if it's our workgroup */
  2990. -      if (strequal(lp_workgroup(), name))
  2991. -    {
  2992. -      extern pstring ServerComment;
  2993. -      add_name_entry(name,0x1e,NB_ACTIVE|NB_GROUP);
  2994. -      add_name_entry(name,0x0 ,NB_ACTIVE|NB_GROUP);
  2995. -      add_server_entry(d,w,myname,w->ServerType,0,ServerComment,True);
  2996. -    }
  2997. -      
  2998. -      DEBUG(3,("Added domain name entry %s at %s\n", name,inet_ntoa(ip)));
  2999. -      return d;
  3000. -    }
  3001. -  return NULL;
  3002. -}
  3003. -
  3004. -/****************************************************************************
  3005. -  add a browser entry
  3006. -  ****************************************************************************/
  3007. -struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
  3008. -                          time_t ttl, struct in_addr ip)
  3009. -{
  3010. -  BOOL newentry=False;
  3011. -  
  3012. -  struct browse_cache_record *b;
  3013. -
  3014. -  /* search for the entry: if it's already in the cache, update that entry */
  3015. -  for (b = browserlist; b; b = b->next)
  3016. -    {
  3017. -      if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break;
  3018. -    }
  3019. -  
  3020. -  if (b && b->synced)
  3021. -    {
  3022. -      /* entries get left in the cache for a while. this stops sync'ing too
  3023. -     often if the network is large */
  3024. -      DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
  3025. -        b->name, b->group, inet_ntoa(b->ip), b->sync_time));
  3026. -      return NULL;
  3027. -    }
  3028. -  
  3029. -  if (!b)
  3030. -    {
  3031. -      newentry = True;
  3032. -      b = (struct browse_cache_record *)malloc(sizeof(*b));
  3033. -      
  3034. -      if (!b) return(NULL);
  3035. -      
  3036. -      bzero((char *)b,sizeof(*b));
  3037. -    }
  3038. -  
  3039. -  /* update the entry */
  3040. -  ttl = time(NULL)+ttl;
  3041. -  
  3042. -  StrnCpy(b->name ,name,sizeof(b->name )-1);
  3043. -  StrnCpy(b->group,wg  ,sizeof(b->group)-1);
  3044. -  strupper(b->name);
  3045. -  strupper(b->group);
  3046. -  
  3047. -  b->ip     = ip;
  3048. -  b->type   = type;
  3049. -  
  3050. -  if (newentry || ttl < b->sync_time) 
  3051. -    b->sync_time = ttl;
  3052. -  
  3053. -  if (newentry)
  3054. -    {
  3055. -      b->synced = False;
  3056. -      add_browse_cache(b);
  3057. -      
  3058. -      DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
  3059. -           wg, name, type, inet_ntoa(ip),ttl));
  3060. -    }
  3061. -  else
  3062. -    {
  3063. -      DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
  3064. -           wg, name, type, inet_ntoa(ip),ttl));
  3065. -    }
  3066. -  
  3067. -  return(b);
  3068. -}
  3069. -
  3070. -
  3071. -/****************************************************************************
  3072. -  add a server entry
  3073. -  ****************************************************************************/
  3074. -struct server_record *add_server_entry(struct subnet_record *d, 
  3075. -                       struct work_record *work,
  3076. -                       char *name,int servertype, 
  3077. -                       int ttl,char *comment,
  3078. -                       BOOL replace)
  3079. -{
  3080. -  BOOL newentry=False;
  3081. -  struct server_record *s;
  3082. -  
  3083. -  if (name[0] == '*')
  3084. -    {
  3085. -      return (NULL);
  3086. -    }
  3087. -  
  3088. -  for (s = work->serverlist; s; s = s->next)
  3089. -    {
  3090. -      if (strequal(name,s->serv.name)) break;
  3091. -    }
  3092. -  
  3093. -  if (s && !replace)
  3094. -    {
  3095. -      DEBUG(4,("Not replacing %s\n",name));
  3096. -      return(s);
  3097. -    }
  3098. -  
  3099. -  updatedlists=True;
  3100. -  
  3101. -  if (!s)
  3102. -    {
  3103. -      newentry = True;
  3104. -      s = (struct server_record *)malloc(sizeof(*s));
  3105. -      
  3106. -      if (!s) return(NULL);
  3107. -      
  3108. -      bzero((char *)s,sizeof(*s));
  3109. -    }
  3110. -  
  3111. -  if (d->my_interface &&
  3112. -      strequal(lp_workgroup(),work->work_group))
  3113. -    {
  3114. -      if (servertype)
  3115. -    servertype |= SV_TYPE_LOCAL_LIST_ONLY;
  3116. -    }
  3117. -  else
  3118. -    {
  3119. -      servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
  3120. -    }
  3121. -  
  3122. -  /* update the entry */
  3123. -  StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
  3124. -  StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
  3125. -  strupper(s->serv.name);
  3126. -  s->serv.type  = servertype;
  3127. -  s->death_time = ttl?time(NULL)+ttl*3:0;
  3128. -
  3129. -  if (servertype == 0)
  3130. -    s->death_time = time(NULL)-1;
  3131. -  
  3132. -  /* for a domain entry, the comment field refers to the server name */
  3133. -  
  3134. -  if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
  3135. -  
  3136. -  if (newentry)
  3137. -    {
  3138. -      add_server(work, s);
  3139. -      
  3140. -      DEBUG(3,("Added "));
  3141. -    }
  3142. -  else
  3143. -    {
  3144. -      DEBUG(3,("Updated "));
  3145. -    }
  3146. -  
  3147. -  DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
  3148. -       name,servertype,comment,
  3149. -       work->work_group,inet_ntoa(d->bcast_ip)));
  3150. -  
  3151. -  return(s);
  3152. -}
  3153. -
  3154. -
  3155. -/*******************************************************************
  3156. -  write out browse.dat
  3157. -  ******************************************************************/
  3158. -void write_browse_list(void)
  3159. -{
  3160. -  struct subnet_record *d;
  3161. -  
  3162. -  pstring fname,fnamenew;
  3163. -  FILE *f;
  3164. -  
  3165. -  if (!updatedlists) return;
  3166. -  
  3167. -  dump_names();
  3168. -  dump_workgroups();
  3169. -  
  3170. -  updatedlists = False;
  3171. -  updatecount++;
  3172. -  
  3173. -  strcpy(fname,lp_lockdir());
  3174. -  trim_string(fname,NULL,"/");
  3175. -  strcat(fname,"/");
  3176. -  strcat(fname,SERVER_LIST);
  3177. -  strcpy(fnamenew,fname);
  3178. -  strcat(fnamenew,".");
  3179. -  
  3180. -  f = fopen(fnamenew,"w");
  3181. -  
  3182. -  if (!f)
  3183. -    {
  3184. -      DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
  3185. -      return;
  3186. -    }
  3187. -  
  3188. -  for (d = subnetlist; d ; d = d->next)
  3189. -    {
  3190. -      struct work_record *work;
  3191. -      for (work = d->workgrouplist; work ; work = work->next)
  3192. -    {
  3193. -      struct server_record *s;
  3194. -      for (s = work->serverlist; s ; s = s->next)
  3195. -        {
  3196. -          fstring tmp;
  3197. -          
  3198. -          /* don't list domains I don't have a master for */
  3199. -          if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) &&
  3200. -          !s->serv.comment[0])
  3201. -        {
  3202. -          continue;
  3203. -        }
  3204. -          
  3205. -          /* output server details, plus what workgroup/domain
  3206. -         they're in. without the domain information, the
  3207. -         combined list of all servers in all workgroups gets
  3208. -         sent to anyone asking about any workgroup! */
  3209. -          
  3210. -          sprintf(tmp, "\"%s\"", s->serv.name);
  3211. -          fprintf(f, "%-25s ", tmp);
  3212. -          fprintf(f, "%08x ", s->serv.type);
  3213. -          sprintf(tmp, "\"%s\" ", s->serv.comment);
  3214. -          fprintf(f, "%-30s", tmp);
  3215. -          fprintf(f, "\"%s\"\n", work->work_group);
  3216. -        }
  3217. -    }
  3218. -    }
  3219. -  
  3220. -  fclose(f);
  3221. -  unlink(fname);
  3222. -  chmod(fnamenew,0644);
  3223. -  rename(fnamenew,fname);   
  3224. -  DEBUG(3,("Wrote browse list %s\n",fname));
  3225. -}
  3226. -
  3227. -
  3228. -/*******************************************************************
  3229. -  expire old servers in the serverlist
  3230. -  ******************************************************************/
  3231. -void expire_servers(time_t t)
  3232. -{
  3233. -  struct subnet_record *d;
  3234. -  
  3235. -  for (d = subnetlist ; d ; d = d->next)
  3236. -    {
  3237. -      struct work_record *work;
  3238. -      
  3239. -      for (work = d->workgrouplist; work; work = work->next)
  3240. -    {
  3241. -      remove_old_servers(work, t);
  3242. -    }
  3243. -    }
  3244. -}
  3245. -
  3246. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbname.c samba-1.9.16alpha11/source/namedbname.c
  3247. --- samba-1.9.16alpha10/source/namedbname.c    Thu Jan  1 10:00:00 1970
  3248. +++ samba-1.9.16alpha11/source/namedbname.c    Thu Jul 18 20:53:15 1996
  3249. @@ -0,0 +1,548 @@
  3250. +/* 
  3251. +   Unix SMB/Netbios implementation.
  3252. +   Version 1.9.
  3253. +   NBT netbios routines and daemon - version 2
  3254. +   Copyright (C) Andrew Tridgell 1994-1996
  3255. +   
  3256. +   This program is free software; you can redistribute it and/or modify
  3257. +   it under the terms of the GNU General Public License as published by
  3258. +   the Free Software Foundation; either version 2 of the License, or
  3259. +   (at your option) any later version.
  3260. +   
  3261. +   This program is distributed in the hope that it will be useful,
  3262. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  3263. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3264. +   GNU General Public License for more details.
  3265. +   
  3266. +   You should have received a copy of the GNU General Public License
  3267. +   along with this program; if not, write to the Free Software
  3268. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3269. +   
  3270. +   Module name: namedbname.c
  3271. +
  3272. +   Revision History:
  3273. +
  3274. +   14 jan 96: lkcl@pires.co.uk
  3275. +   added multiple workgroup domain master support
  3276. +
  3277. +   04 jul 96: lkcl@pires.co.uk
  3278. +   created module namedbname containing name database functions
  3279. +*/
  3280. +
  3281. +#include "includes.h"
  3282. +
  3283. +extern int DEBUGLEVEL;
  3284. +
  3285. +extern pstring scope;
  3286. +extern struct in_addr ipzero;
  3287. +extern struct in_addr ipgrp;
  3288. +
  3289. +extern struct subnet_record *subnetlist;
  3290. +
  3291. +#define WINS_LIST "wins.dat"
  3292. +
  3293. +
  3294. +/****************************************************************************
  3295. +  true if two netbios names are equal
  3296. +****************************************************************************/
  3297. +BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
  3298. +{
  3299. +  return n1->name_type == n2->name_type &&
  3300. +         strequal(n1->name ,n2->name ) &&
  3301. +         strequal(n1->scope,n2->scope);
  3302. +}
  3303. +
  3304. +
  3305. +/****************************************************************************
  3306. +  true if the netbios name is ^1^2__MSBROWSE__^2^1
  3307. +
  3308. +  note: this name is registered if as a master browser or backup browser
  3309. +  you are responsible for a workgroup (when you announce a domain by
  3310. +  broadcasting on your local subnet, you announce it as coming from this
  3311. +  name: see announce_host()).
  3312. +
  3313. +  **************************************************************************/
  3314. +BOOL ms_browser_name(char *name, int type)
  3315. +{
  3316. +  return strequal(name,MSBROWSE) && type == 0x01;
  3317. +}
  3318. +
  3319. +
  3320. +/****************************************************************************
  3321. +  add a netbios name into the namelist
  3322. +  **************************************************************************/
  3323. +static void add_name(struct subnet_record *d, struct name_record *n)
  3324. +{
  3325. +  struct name_record *n2;
  3326. +
  3327. +  if (!d) return;
  3328. +
  3329. +  if (!d->namelist)
  3330. +  {
  3331. +    d->namelist = n;
  3332. +    n->prev = NULL;
  3333. +    n->next = NULL;
  3334. +    return;
  3335. +  }
  3336. +
  3337. +  for (n2 = d->namelist; n2->next; n2 = n2->next) ;
  3338. +
  3339. +  n2->next = n;
  3340. +  n->next = NULL;
  3341. +  n->prev = n2;
  3342. +}
  3343. +
  3344. +
  3345. +/****************************************************************************
  3346. +  remove a name from the namelist. The pointer must be an element just 
  3347. +  retrieved
  3348. +  **************************************************************************/
  3349. +void remove_name(struct subnet_record *d, struct name_record *n)
  3350. +{
  3351. +  struct name_record *nlist;
  3352. +  if (!d) return;
  3353. +
  3354. +  nlist = d->namelist;
  3355. +
  3356. +  while (nlist && nlist != n) nlist = nlist->next;
  3357. +
  3358. +  if (nlist)
  3359. +  {
  3360. +    if (nlist->next) nlist->next->prev = nlist->prev;
  3361. +    if (nlist->prev) nlist->prev->next = nlist->next;
  3362. +    free(nlist);
  3363. +  }
  3364. +}
  3365. +
  3366. +
  3367. +/****************************************************************************
  3368. +  find a name in a namelist.
  3369. +  **************************************************************************/
  3370. +struct name_record *find_name(struct name_record *n,
  3371. +            struct nmb_name *name,
  3372. +            int search)
  3373. +{
  3374. +    struct name_record *ret;
  3375. +  
  3376. +    for (ret = n; ret; ret = ret->next)
  3377. +    {
  3378. +        if (name_equal(&ret->name,name))
  3379. +        {
  3380. +            /* self search: self names only */
  3381. +            if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
  3382. +                continue;
  3383. +      
  3384. +            return ret;
  3385. +        }
  3386. +    }
  3387. +    return NULL;
  3388. +}
  3389. +
  3390. +
  3391. +/****************************************************************************
  3392. +  find a name in the domain database namelist 
  3393. +  search can be any of:
  3394. +  FIND_SELF - look exclusively for names the samba server has added for itself
  3395. +  FIND_LOCAL - look for names in the local subnet record.
  3396. +  FIND_WINS - look for names in the WINS record
  3397. +  **************************************************************************/
  3398. +struct name_record *find_name_search(struct subnet_record **d,
  3399. +            struct nmb_name *name,
  3400. +            int search, struct in_addr ip)
  3401. +{
  3402. +    if (d == NULL) return NULL; /* bad error! */
  3403. +    
  3404. +    if ((search & FIND_LOCAL) == FIND_LOCAL)
  3405. +    {
  3406. +        if (*d != NULL)
  3407. +        {
  3408. +            DEBUG(4,("find_name on local: %s %s search %x\n",
  3409. +                        namestr(name),inet_ntoa(ip), search));
  3410. +            return find_name((*d)->namelist, name, search);
  3411. +        }
  3412. +        else
  3413. +        {
  3414. +            DEBUG(4,("local find_name_search with a NULL subnet pointer\n"));
  3415. +            return NULL;
  3416. +        }
  3417. +    }
  3418. +
  3419. +    if ((search & FIND_WINS) != FIND_WINS) return NULL;
  3420. +
  3421. +    if (*d == NULL)
  3422. +    {
  3423. +        /* find WINS subnet record */
  3424. +        *d = find_subnet(ipgrp);
  3425. +    }
  3426. +
  3427. +    if (*d == NULL) return NULL;
  3428. +
  3429. +    DEBUG(4,("find_name on WINS: %s %s search %x\n",
  3430. +                        namestr(name),inet_ntoa(ip), search));
  3431. +    return find_name((*d)->namelist, name, search);
  3432. +}
  3433. +
  3434. +
  3435. +/****************************************************************************
  3436. +  dump a copy of the name table
  3437. +  **************************************************************************/
  3438. +void dump_names(void)
  3439. +{
  3440. +  struct name_record *n;
  3441. +  struct subnet_record *d;
  3442. +  fstring fname, fnamenew;
  3443. +  time_t t = time(NULL);
  3444. +  
  3445. +  FILE *f;
  3446. +  
  3447. +  strcpy(fname,lp_lockdir());
  3448. +  trim_string(fname,NULL,"/");
  3449. +  strcat(fname,"/");
  3450. +  strcat(fname,WINS_LIST);
  3451. +  strcpy(fnamenew,fname);
  3452. +  strcat(fnamenew,".");
  3453. +  
  3454. +  f = fopen(fnamenew,"w");
  3455. +  
  3456. +  if (!f)
  3457. +  {
  3458. +    DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
  3459. +  }
  3460. +  
  3461. +  DEBUG(3,("Dump of local name table:\n"));
  3462. +  
  3463. +  for (d = subnetlist; d; d = d->next)
  3464. +   for (n = d->namelist; n; n = n->next)
  3465. +    {
  3466. +      if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER)
  3467. +      {
  3468. +        fstring data;
  3469. +
  3470. +      /* XXXX i have little imagination as to how to output nb_flags as
  3471. +         anything other than as a hexadecimal number :-) */
  3472. +
  3473. +        sprintf(data, "%s#%02x %s %2x %ld",
  3474. +           n->name.name,n->name.name_type, /* XXXX ignore the scope for now */
  3475. +           inet_ntoa(n->ip),
  3476. +           n->nb_flags,
  3477. +           n->death_time);
  3478. +        fprintf(f, "%s\n", data);
  3479. +      }
  3480. +
  3481. +      DEBUG(3,("%15s ", inet_ntoa(d->bcast_ip)));
  3482. +      DEBUG(3,("%15s ", inet_ntoa(d->mask_ip)));
  3483. +      DEBUG(3,("%-19s %15s NB=%2x TTL=%ld \n",
  3484. +           namestr(&n->name),
  3485. +           inet_ntoa(n->ip),
  3486. +           n->nb_flags,
  3487. +           n->death_time?n->death_time-t:0));
  3488. +    }
  3489. +
  3490. +  fclose(f);
  3491. +  unlink(fname);
  3492. +  chmod(fnamenew,0644);
  3493. +  rename(fnamenew,fname);   
  3494. +
  3495. +  DEBUG(3,("Wrote wins database %s\n",fname));
  3496. +}
  3497. +
  3498. +
  3499. +/****************************************************************************
  3500. +load a netbios name database file
  3501. +****************************************************************************/
  3502. +void load_netbios_names(void)
  3503. +{
  3504. +  struct subnet_record *d = find_subnet(ipgrp);
  3505. +  fstring fname;
  3506. +
  3507. +  FILE *f;
  3508. +  pstring line;
  3509. +
  3510. +  if (!d) return;
  3511. +
  3512. +  strcpy(fname,lp_lockdir());
  3513. +  trim_string(fname,NULL,"/");
  3514. +  strcat(fname,"/");
  3515. +  strcat(fname,WINS_LIST);
  3516. +
  3517. +  f = fopen(fname,"r");
  3518. +
  3519. +  if (!f) {
  3520. +    DEBUG(2,("Can't open wins database file %s\n",fname));
  3521. +    return;
  3522. +  }
  3523. +
  3524. +  while (!feof(f))
  3525. +    {
  3526. +      pstring name_str, ip_str, ttd_str, nb_flags_str;
  3527. +
  3528. +      pstring name;
  3529. +      int type = 0;
  3530. +      int nb_flags;
  3531. +      time_t ttd;
  3532. +      struct in_addr ipaddr;
  3533. +
  3534. +      enum name_source source;
  3535. +
  3536. +      char *ptr;
  3537. +      int count = 0;
  3538. +
  3539. +      char *p;
  3540. +
  3541. +      if (!fgets_slash(line,sizeof(pstring),f)) continue;
  3542. +
  3543. +      if (*line == '#') continue;
  3544. +
  3545. +    ptr = line;
  3546. +
  3547. +    if (next_token(&ptr,name_str    ,NULL)) ++count;
  3548. +    if (next_token(&ptr,ip_str      ,NULL)) ++count;
  3549. +    if (next_token(&ptr,ttd_str     ,NULL)) ++count;
  3550. +    if (next_token(&ptr,nb_flags_str,NULL)) ++count;
  3551. +
  3552. +    if (count <= 0) continue;
  3553. +
  3554. +    if (count != 4) {
  3555. +      DEBUG(0,("Ill formed wins line"));
  3556. +      DEBUG(0,("[%s]: name#type ip nb_flags abs_time\n",line));
  3557. +      continue;
  3558. +    }
  3559. +
  3560. +      /* netbios name. # divides the name from the type (hex): netbios#xx */
  3561. +      strcpy(name,name_str);
  3562. +
  3563. +      p = strchr(name,'#');
  3564. +
  3565. +      if (p) {
  3566. +        *p = 0;
  3567. +        sscanf(p+1,"%x",&type);
  3568. +      }
  3569. +
  3570. +      /* decode the netbios flags (hex) and the time-to-die (seconds) */
  3571. +      sscanf(nb_flags_str,"%x",&nb_flags);
  3572. +      sscanf(ttd_str,"%ld",&ttd);
  3573. +
  3574. +      ipaddr = *interpret_addr2(ip_str);
  3575. +
  3576. +      if (ip_equal(ipaddr,ipzero)) {
  3577. +         source = SELF;
  3578. +      }
  3579. +      else
  3580. +      {
  3581. +         source = REGISTER;
  3582. +      }
  3583. +
  3584. +      DEBUG(4, ("add WINS line: %s#%02x %s %ld %2x\n",
  3585. +           name,type, inet_ntoa(ipaddr), ttd, nb_flags));
  3586. +
  3587. +      /* add all entries that have 60 seconds or more to live */
  3588. +      if (ttd - 60 < time(NULL) || ttd == 0)
  3589. +      {
  3590. +        time_t t = (ttd?ttd-time(NULL):0) / 3;
  3591. +
  3592. +        /* add netbios entry read from the wins.dat file. IF it's ok */
  3593. +        add_netbios_entry(d,name,type,nb_flags,t,source,ipaddr,True,True);
  3594. +      }
  3595. +    }
  3596. +
  3597. +  fclose(f);
  3598. +}
  3599. +
  3600. +
  3601. +/****************************************************************************
  3602. +  remove an entry from the name list
  3603. +  ****************************************************************************/
  3604. +void remove_netbios_name(struct subnet_record *d,
  3605. +            char *name,int type, enum name_source source,
  3606. +             struct in_addr ip)
  3607. +{
  3608. +  struct nmb_name nn;
  3609. +  struct name_record *n;
  3610. +
  3611. +  make_nmb_name(&nn, name, type, scope);
  3612. +  n = find_name_search(&d, &nn, FIND_LOCAL, ip);
  3613. +  
  3614. +  if (n && n->source == source) remove_name(d,n);
  3615. +}
  3616. +
  3617. +
  3618. +/****************************************************************************
  3619. +  add an entry to the name list.
  3620. +
  3621. +  this is a multi-purpose function.
  3622. +
  3623. +  it adds samba's own names in to its records on each interface, keeping a
  3624. +  record of whether it is a master browser, domain master, or WINS server.
  3625. +
  3626. +  it also keeps a record of WINS entries.
  3627. +
  3628. +  ****************************************************************************/
  3629. +struct name_record *add_netbios_entry(struct subnet_record *d,
  3630. +        char *name, int type, int nb_flags, 
  3631. +        int ttl, enum name_source source, struct in_addr ip,
  3632. +        BOOL new_only,BOOL wins)
  3633. +{
  3634. +  struct name_record *n;
  3635. +  struct name_record *n2=NULL;
  3636. +  int search = 0;
  3637. +  BOOL self = source == SELF;
  3638. +
  3639. +  /* add the name to the WINS list if the name comes from a directed query */
  3640. +  search |= wins ? FIND_WINS : FIND_LOCAL;
  3641. +  /* search for SELF names only */
  3642. +  search |= self ? FIND_SELF : 0;
  3643. +
  3644. +  if (!self)
  3645. +  {
  3646. +    if (!wins && type != 0x1b)
  3647. +    {
  3648. +       /* the only broadcast (non-WINS) names we are adding are ours
  3649. +          (SELF) and PDC type names */
  3650. +       return NULL;
  3651. +    }
  3652. +  }
  3653. +
  3654. +  n = (struct name_record *)malloc(sizeof(*n));
  3655. +  if (!n) return(NULL);
  3656. +
  3657. +  bzero((char *)n,sizeof(*n));
  3658. +
  3659. +  make_nmb_name(&n->name,name,type,scope);
  3660. +
  3661. +  if ((n2 = find_name_search(&d, &n->name, search, new_only?ipzero:ip)))
  3662. +  {
  3663. +    free(n);
  3664. +    if (new_only || (n2->source==SELF && source!=SELF)) return n2;
  3665. +    n = n2;
  3666. +  }
  3667. +
  3668. +  if (ttl)
  3669. +     n->death_time = time(NULL)+ttl*3;
  3670. +  n->refresh_time = time(NULL)+GET_TTL(ttl);
  3671. +
  3672. +  n->ip = ip;
  3673. +  n->nb_flags = nb_flags;
  3674. +  n->source = source;
  3675. +  
  3676. +  if (!n2) add_name(d,n);
  3677. +
  3678. +  DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
  3679. +            namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
  3680. +
  3681. +  return(n);
  3682. +}
  3683. +
  3684. +
  3685. +/*******************************************************************
  3686. +  expires old names in the namelist
  3687. +  ******************************************************************/
  3688. +void expire_names(time_t t)
  3689. +{
  3690. +    struct name_record *n;
  3691. +    struct name_record *next;
  3692. +    struct subnet_record *d;
  3693. +
  3694. +    /* expire old names */
  3695. +    for (d = subnetlist; d; d = d->next)
  3696. +    {
  3697. +      for (n = d->namelist; n; n = next)
  3698. +        {
  3699. +          if (n->death_time && n->death_time < t)
  3700. +        {
  3701. +          DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
  3702. +          
  3703. +          next = n->next;
  3704. +          
  3705. +          if (n->prev) n->prev->next = n->next;
  3706. +          if (n->next) n->next->prev = n->prev;
  3707. +          
  3708. +          if (d->namelist == n) d->namelist = n->next; 
  3709. +          
  3710. +          free(n);
  3711. +        }
  3712. +          else
  3713. +        {
  3714. +          next = n->next;
  3715. +        }
  3716. +        }
  3717. +    }
  3718. +}
  3719. +
  3720. +
  3721. +/***************************************************************************
  3722. +  reply to a name query
  3723. +  ****************************************************************************/
  3724. +struct name_record *search_for_name(struct subnet_record **d,
  3725. +                    struct nmb_name *question,
  3726. +                    struct in_addr ip, int Time, int search)
  3727. +{
  3728. +  int name_type = question->name_type;
  3729. +  char *qname = question->name;
  3730. +  BOOL dns_type = name_type == 0x20 || name_type == 0;
  3731. +  
  3732. +  struct name_record *n;
  3733. +  
  3734. +  DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
  3735. +  
  3736. +  /* first look up name in cache */
  3737. +  n = find_name_search(d,question,search,ip);
  3738. +  
  3739. +  if (*d == NULL) return NULL;
  3740. +
  3741. +  DEBUG(4,("subnet %s ", inet_ntoa((*d)->bcast_ip)));
  3742. +
  3743. +  /* now try DNS lookup. */
  3744. +  if (!n)
  3745. +    {
  3746. +      struct in_addr dns_ip;
  3747. +      unsigned long a;
  3748. +      
  3749. +      /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
  3750. +      if (!dns_type && name_type != 0x1b)
  3751. +    {
  3752. +      DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
  3753. +      return NULL;
  3754. +    }
  3755. +      
  3756. +      /* look it up with DNS */      
  3757. +      a = interpret_addr(qname);
  3758. +      
  3759. +      putip((char *)&dns_ip,(char *)&a);
  3760. +      
  3761. +      if (!a)
  3762. +    {
  3763. +      /* no luck with DNS. We could possibly recurse here XXXX */
  3764. +      DEBUG(3,("no recursion.\n"));
  3765. +      /* add the fail to our WINS cache of names. give it 1 hour in the cache */
  3766. +      add_netbios_entry(*d,qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,
  3767. +                        True, True);
  3768. +      return NULL;
  3769. +    }
  3770. +      
  3771. +      /* add it to our WINS cache of names. give it 2 hours in the cache */
  3772. +      n = add_netbios_entry(*d,qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip,
  3773. +                        True,True);
  3774. +      
  3775. +      /* failed to add it? yikes! */
  3776. +      if (!n) return NULL;
  3777. +    }
  3778. +  
  3779. +  /* is our entry already dead? */
  3780. +  if (n->death_time)
  3781. +    {
  3782. +      if (n->death_time < Time) return False;
  3783. +    }
  3784. +  
  3785. +  /* it may have been an earlier failure */
  3786. +  if (n->source == DNSFAIL)
  3787. +    {
  3788. +      DEBUG(3,("DNSFAIL\n"));
  3789. +      return NULL;
  3790. +    }
  3791. +  
  3792. +  DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));      
  3793. +  
  3794. +  return n;
  3795. +}
  3796. +
  3797. +
  3798. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbname.doc samba-1.9.16alpha11/source/namedbname.doc
  3799. --- samba-1.9.16alpha10/source/namedbname.doc    Thu Jan  1 10:00:00 1970
  3800. +++ samba-1.9.16alpha11/source/namedbname.doc    Sun Jul  7 22:35:55 1996
  3801. @@ -0,0 +1,155 @@
  3802. +this module deals with the NetBIOS name database for samba. it deals
  3803. +directly with adding, removing, finding, loading and saving of names.
  3804. +
  3805. +/*************************************************************************
  3806. +  search_for_name()
  3807. +  *************************************************************************/
  3808. +
  3809. +this function is responsible for finding a name in the appropriate part
  3810. +of samba's NetBIOS name database. if the name cannot be found, then it
  3811. +should look the name up using DNS. later modifications will be to
  3812. +forward the request on to another WINS server, should samba not be able
  3813. +to find out about the requested name (this will be implemented through
  3814. +issuing a new type of samba 'state').
  3815. +
  3816. +the name is first searched for in the NetBIOS cache. if it cannot be
  3817. +found, then it if the name looks like it's a server-type name (0x20
  3818. +0x0 or 0x1b) then DNS is used to look for the name.
  3819. +
  3820. +if DNS fails, then a record of this failure is kept. if it succeeds, then
  3821. +a new NetBIOS entry is added.
  3822. +
  3823. +the successfully found name is returned. on failure, NULL is returned.
  3824. +
  3825. +
  3826. +/*************************************************************************
  3827. +  expire_names()
  3828. +  *************************************************************************/
  3829. +
  3830. +this function is responsible for removing old NetBIOS names from its
  3831. +database. no further action is required.
  3832. +
  3833. +for over-zealous WINS systems, the use of query_refresh_names() is
  3834. +recommended. this function initiates polling of hosts that have
  3835. +registered with samba in its capacity as a WINS server. an alternative
  3836. +means to achieve the same end as query_refresh_names() is to
  3837. +reduce the time to live when the name is registered with samba,
  3838. +except that in this instance the responsibility for refreshing the
  3839. +name is with the owner of the name, not the server with which the name
  3840. +is registered. 
  3841. +
  3842. +
  3843. +/*************************************************************************
  3844. +  add_netbios_entry()
  3845. +  *************************************************************************/
  3846. +
  3847. +this function is responsible for adding or updating a NetBIOS name
  3848. +in the database. into the local interface records, the only names
  3849. +that will be added are those of primary domain controllers and
  3850. +samba's own names. into the WINS records, all names are added.
  3851. +
  3852. +the name to be added / updated will be looked up in the records.
  3853. +if it is found, then we will not overwrite the entry if the flag
  3854. +'newonly' is True, or if the name is being added as a non-SELF
  3855. +(non-samba) name and the records indicate that samba owns the
  3856. +name.
  3857. +
  3858. +otherwise, the name is added or updated with the new details.
  3859. +
  3860. +
  3861. +/*************************************************************************
  3862. +  remove_netbios_entry()
  3863. +  *************************************************************************/
  3864. +
  3865. +this function is responsible for removing a NetBIOS entry from
  3866. +the database. the name is searched for in the records using
  3867. +find_name_search(). if the ip is zero, then the ip is ignored.
  3868. +
  3869. +the name is removed if the expected source (e.g SELF, REGISTER)
  3870. +matches that in the database.
  3871. +
  3872. +
  3873. +/*************************************************************************
  3874. +  load_netbios_names()
  3875. +  *************************************************************************/
  3876. +
  3877. +this function is responsible for loading any NetBIOS names that samba,
  3878. +in its WINS capacity, has written out to disk. all the relevant details
  3879. +are recorded in this file, including the time-to-live. should the 
  3880. +time left to live be small, the name is not added back in to samba's
  3881. +WINS database.
  3882. +
  3883. +/*************************************************************************
  3884. +  dump_names()
  3885. +  *************************************************************************/
  3886. +
  3887. +this function is responsible for outputting NetBIOS names in two formats.
  3888. +firstly, as debugging information, and secondly, all names that have been
  3889. +registered with samba in its capacity as a WINS server are written to
  3890. +disk.
  3891. +
  3892. +writing all WINS names allows two things. firstly, if samba's NetBIOS
  3893. +daemon dies or is terminated, on restarting the daemon most if not all
  3894. +of the registered WINS names will be preserved (which is a good reason
  3895. +why query_netbios_names() should be used).
  3896. +
  3897. +/*************************************************************************
  3898. +  find_name_search()
  3899. +  *************************************************************************/
  3900. +
  3901. +this function is a wrapper around find_name(). find_name_search() can
  3902. +be told whether to search for the name in a local subnet structure or
  3903. +in the WINS database. on top of this, it can be told to search only
  3904. +for samba's SELF names.
  3905. +
  3906. +if it finds the name in the WINS database, it will set the subnet_record
  3907. +and also return the name it finds.
  3908. +
  3909. +/*************************************************************************
  3910. +  find_name()
  3911. +  *************************************************************************/
  3912. +
  3913. +this function is a low-level search function that searches a single
  3914. +interface's NetBIOS records for a name. if the ip to be found is
  3915. +zero then the ip address is ignored. this is to enable a name to
  3916. +be found without knowing its ip address, and also to find the exact
  3917. +name if a large number of group names are added with different ip
  3918. +addresses.
  3919. +
  3920. +
  3921. +/*************************************************************************
  3922. +  remove_name()
  3923. +  *************************************************************************/
  3924. +
  3925. +this function is responsible for removing a specific NetBIOS entry
  3926. +from a subnet list's records. only if the pointer to the entry is
  3927. +in the list will the name be removed.
  3928. +
  3929. +
  3930. +/*************************************************************************
  3931. +  add_name()
  3932. +  *************************************************************************/
  3933. +
  3934. +this function is responsible for adding a NetBIOS entry into a
  3935. +subnet list's records.
  3936. +
  3937. +
  3938. +/*************************************************************************
  3939. +  ms_browser_name()
  3940. +  *************************************************************************/
  3941. +
  3942. +this function returns True if the NetBIOS name passed to it is
  3943. +^1^2__MSBROWSE__^2^1
  3944. +
  3945. +
  3946. +/*************************************************************************
  3947. +  name_equal()
  3948. +  *************************************************************************/
  3949. +
  3950. +this function returns True if the two NetBIOS names passed to it
  3951. +match in name, type and scope: the NetBIOS names are equal.
  3952. +
  3953. +
  3954. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbresp.c samba-1.9.16alpha11/source/namedbresp.c
  3955. --- samba-1.9.16alpha10/source/namedbresp.c    Thu Jan  1 10:00:00 1970
  3956. +++ samba-1.9.16alpha11/source/namedbresp.c    Wed Jul 10 04:01:24 1996
  3957. @@ -0,0 +1,156 @@
  3958. +/* 
  3959. +   Unix SMB/Netbios implementation.
  3960. +   Version 1.9.
  3961. +   NBT netbios library routines
  3962. +   Copyright (C) Andrew Tridgell 1994-1996
  3963. +   
  3964. +   This program is free software; you can redistribute it and/or modify
  3965. +   it under the terms of the GNU General Public License as published by
  3966. +   the Free Software Foundation; either version 2 of the License, or
  3967. +   (at your option) any later version.
  3968. +   
  3969. +   This program is distributed in the hope that it will be useful,
  3970. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  3971. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3972. +   GNU General Public License for more details.
  3973. +   
  3974. +   You should have received a copy of the GNU General Public License
  3975. +   along with this program; if not, write to the Free Software
  3976. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3977. +   
  3978. +   Module name: namedbresp.c
  3979. +
  3980. +*/
  3981. +
  3982. +#include "includes.h"
  3983. +
  3984. +extern int ClientNMB;
  3985. +extern int ClientDGRAM;
  3986. +
  3987. +extern struct subnet_record *subnetlist;
  3988. +
  3989. +extern int DEBUGLEVEL;
  3990. +
  3991. +extern pstring scope;
  3992. +extern pstring myname;
  3993. +extern struct in_addr ipzero;
  3994. +extern struct in_addr ipgrp;
  3995. +
  3996. +int num_response_packets = 0;
  3997. +
  3998. +/***************************************************************************
  3999. +  add an expected response record into the list
  4000. +  **************************************************************************/
  4001. +void add_response_record(struct subnet_record *d,
  4002. +                struct response_record *n)
  4003. +{
  4004. +  struct response_record *n2;
  4005. +
  4006. +  if (!d) return;
  4007. +
  4008. +  num_response_packets++; /* count of total number of packets still around */
  4009. +
  4010. +  DEBUG(4,("adding response record id:%d num_records:%d\n",
  4011. +                   n->response_id, num_response_packets));
  4012. +
  4013. +  if (!d->responselist)
  4014. +    {
  4015. +      d->responselist = n;
  4016. +      n->prev = NULL;
  4017. +      n->next = NULL;
  4018. +      return;
  4019. +    }
  4020. +  
  4021. +  for (n2 = d->responselist; n2->next; n2 = n2->next) ;
  4022. +  
  4023. +  n2->next = n;
  4024. +  n->next = NULL;
  4025. +  n->prev = n2;
  4026. +}
  4027. +
  4028. +
  4029. +/***************************************************************************
  4030. +  remove an expected response record from the list
  4031. +  **************************************************************************/
  4032. +void remove_response_record(struct subnet_record *d,
  4033. +                struct response_record *n)
  4034. +{
  4035. +    if (!d) return;
  4036. +
  4037. +    if (n->prev) n->prev->next = n->next;
  4038. +    if (n->next) n->next->prev = n->prev;
  4039. +
  4040. +    if (d->responselist == n) d->responselist = n->next; 
  4041. +
  4042. +    free(n);
  4043. +
  4044. +    num_response_packets--; /* count of total number of packets still around */
  4045. +}
  4046. +
  4047. +
  4048. +/****************************************************************************
  4049. +  create a name query response record
  4050. +  **************************************************************************/
  4051. +struct response_record *make_response_queue_record(enum state_type state,
  4052. +                int id,uint16 fd,
  4053. +                int quest_type, char *name,int type, int nb_flags, time_t ttl,
  4054. +                BOOL bcast,BOOL recurse,
  4055. +                struct in_addr send_ip, struct in_addr reply_to_ip)
  4056. +{
  4057. +  struct response_record *n;
  4058. +    
  4059. +  if (!name || !name[0]) return NULL;
  4060. +    
  4061. +  if (!(n = (struct response_record *)malloc(sizeof(*n)))) 
  4062. +    return(NULL);
  4063. +
  4064. +  n->response_id = id;
  4065. +  n->state = state;
  4066. +  n->fd = fd;
  4067. +  n->quest_type = quest_type;
  4068. +  make_nmb_name(&n->name, name, type, scope);
  4069. +  n->nb_flags = nb_flags;
  4070. +  n->ttl = ttl;
  4071. +  n->bcast = bcast;
  4072. +  n->recurse = recurse;
  4073. +  n->send_ip = send_ip;
  4074. +  n->reply_to_ip = reply_to_ip;
  4075. +
  4076. +  n->repeat_interval = 1; /* XXXX should be in ms */
  4077. +  n->repeat_count = 3; /* 3 retries */
  4078. +  n->repeat_time = time(NULL) + n->repeat_interval; /* initial retry time */
  4079. +
  4080. +  n->num_msgs = 0;
  4081. +
  4082. +  return n;
  4083. +}
  4084. +
  4085. +
  4086. +/****************************************************************************
  4087. +  find a response in a subnet's name query response list. 
  4088. +  **************************************************************************/
  4089. +struct response_record *find_response_record(struct subnet_record **d,
  4090. +                uint16 id)
  4091. +{  
  4092. +  struct response_record *n;
  4093. +
  4094. +  if (!d) return NULL;
  4095. +
  4096. +  for ((*d) = subnetlist; (*d); (*d) = (*d)->next)
  4097. +  {
  4098. +    for (n = (*d)->responselist; n; n = n->next)
  4099. +    {
  4100. +      if (n->response_id == id) {
  4101. +         DEBUG(4, ("found response record on %s: %d\n",
  4102. +                    inet_ntoa((*d)->bcast_ip), id));
  4103. +         return n;
  4104. +      }
  4105. +    }
  4106. +  }
  4107. +
  4108. +  *d = NULL;
  4109. +
  4110. +  return NULL;
  4111. +}
  4112. +
  4113. +
  4114. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbresp.doc samba-1.9.16alpha11/source/namedbresp.doc
  4115. --- samba-1.9.16alpha10/source/namedbresp.doc    Thu Jan  1 10:00:00 1970
  4116. +++ samba-1.9.16alpha11/source/namedbresp.doc    Thu Jul 11 04:48:26 1996
  4117. @@ -0,0 +1,48 @@
  4118. +module namedbresp deals with the maintenance of the list of expected
  4119. +responses - creating, finding and removal.
  4120. +
  4121. +module nameresp deals with the initial transmission, re-transmission
  4122. +and time-out of netbios response records.
  4123. +
  4124. +
  4125. +/*************************************************************************
  4126. +  find_response_record()
  4127. +  *************************************************************************/
  4128. +
  4129. +this function is responsible for matching the unique response transaction
  4130. +id with an expected response record. as a side-effect of this search,
  4131. +it will find the subnet (or the WINS pseudo-subnet) that samba expected
  4132. +the response to come from.
  4133. +
  4134. +
  4135. +/*************************************************************************
  4136. +  make_response_queue_record()
  4137. +  *************************************************************************/
  4138. +
  4139. +this function is responsible for creating a response record, which will
  4140. +be queued awaiting a response.
  4141. +
  4142. +the number of retries is set to 3, and the retry period set to 1 second.
  4143. +if no response is received, then the packet is re-transmitted, which is
  4144. +why so much information is stored in the response record.
  4145. +
  4146. +the number of expected responses queued is kept, so listen_for_packets()
  4147. +knows it must time-out after 1 second if one or more responses are
  4148. +expected.
  4149. +
  4150. +
  4151. +/*************************************************************************
  4152. +  remove_response_record()
  4153. +  *************************************************************************/
  4154. +
  4155. +this function is responsible for removing a response record from the
  4156. +expected response queue. the number of expected responses is decreased.
  4157. +
  4158. +
  4159. +/*************************************************************************
  4160. +  add_response_record()
  4161. +  *************************************************************************/
  4162. +
  4163. +this function is responsible for adding the response record created by
  4164. +make_response_queue_record() into the appropriate response record queue.
  4165. +
  4166. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbserver.c samba-1.9.16alpha11/source/namedbserver.c
  4167. --- samba-1.9.16alpha10/source/namedbserver.c    Thu Jan  1 10:00:00 1970
  4168. +++ samba-1.9.16alpha11/source/namedbserver.c    Thu Jul 18 20:53:15 1996
  4169. @@ -0,0 +1,221 @@
  4170. +/* 
  4171. +   Unix SMB/Netbios implementation.
  4172. +   Version 1.9.
  4173. +   NBT netbios routines and daemon - version 2
  4174. +   Copyright (C) Andrew Tridgell 1994-1996
  4175. +   
  4176. +   This program is free software; you can redistribute it and/or modify
  4177. +   it under the terms of the GNU General Public License as published by
  4178. +   the Free Software Foundation; either version 2 of the License, or
  4179. +   (at your option) any later version.
  4180. +   
  4181. +   This program is distributed in the hope that it will be useful,
  4182. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  4183. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4184. +   GNU General Public License for more details.
  4185. +   
  4186. +   You should have received a copy of the GNU General Public License
  4187. +   along with this program; if not, write to the Free Software
  4188. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4189. +   
  4190. +   Revision History:
  4191. +
  4192. +   14 jan 96: lkcl@pires.co.uk
  4193. +   added multiple workgroup domain master support
  4194. +
  4195. +   04 jul 96: lkcl@pires.co.uk
  4196. +   created module namedbserver containing server database functions
  4197. +
  4198. +*/
  4199. +
  4200. +#include "includes.h"
  4201. +#include "smb.h"
  4202. +
  4203. +extern int ClientNMB;
  4204. +extern int ClientDGRAM;
  4205. +
  4206. +extern int DEBUGLEVEL;
  4207. +
  4208. +extern pstring myname;
  4209. +
  4210. +/* this is our domain/workgroup/server database */
  4211. +extern struct subnet_record *subnetlist;
  4212. +
  4213. +extern BOOL updatedlists;
  4214. +
  4215. +
  4216. +/*******************************************************************
  4217. +  expire old servers in the serverlist
  4218. +  time of -1 indicates everybody dies except those with time of 0
  4219. +  remove_all_servers indicates everybody dies.
  4220. +  ******************************************************************/
  4221. +void remove_old_servers(struct work_record *work, time_t t,
  4222. +                    BOOL remove_all)
  4223. +{
  4224. +  struct server_record *s;
  4225. +  struct server_record *nexts;
  4226. +  
  4227. +  /* expire old entries in the serverlist */
  4228. +  for (s = work->serverlist; s; s = nexts)
  4229. +    {
  4230. +      if (remove_all || (s->death_time && (t == -1 || s->death_time < t)))
  4231. +    {
  4232. +      DEBUG(3,("Removing dead server %s\n",s->serv.name));
  4233. +      updatedlists = True;
  4234. +      nexts = s->next;
  4235. +      
  4236. +      if (s->prev) s->prev->next = s->next;
  4237. +      if (s->next) s->next->prev = s->prev;
  4238. +      
  4239. +      if (work->serverlist == s) 
  4240. +        work->serverlist = s->next; 
  4241. +
  4242. +      free(s);
  4243. +    }
  4244. +      else
  4245. +    {
  4246. +      nexts = s->next;
  4247. +    }
  4248. +    }
  4249. +}
  4250. +
  4251. +
  4252. +/***************************************************************************
  4253. +  add a server into the list
  4254. +  **************************************************************************/
  4255. +static void add_server(struct work_record *work,struct server_record *s)
  4256. +{
  4257. +  struct server_record *s2;
  4258. +
  4259. +  if (!work->serverlist) {
  4260. +    work->serverlist = s;
  4261. +    s->prev = NULL;
  4262. +    s->next = NULL;
  4263. +    return;
  4264. +  }
  4265. +
  4266. +  for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
  4267. +
  4268. +  s2->next = s;
  4269. +  s->next = NULL;
  4270. +  s->prev = s2;
  4271. +}
  4272. +
  4273. +
  4274. +/****************************************************************************
  4275. +  find a server in a server list.
  4276. +  **************************************************************************/
  4277. +struct server_record *find_server(struct work_record *work, char *name)
  4278. +{
  4279. +    struct server_record *ret;
  4280. +  
  4281. +    if (!work) return NULL;
  4282. +
  4283. +    for (ret = work->serverlist; ret; ret = ret->next)
  4284. +    {
  4285. +        if (strequal(ret->serv.name,name))
  4286. +        {
  4287. +            return ret;
  4288. +        }
  4289. +    }
  4290. +    return NULL;
  4291. +}
  4292. +
  4293. +
  4294. +/****************************************************************************
  4295. +  add a server entry
  4296. +  ****************************************************************************/
  4297. +struct server_record *add_server_entry(struct subnet_record *d, 
  4298. +                       struct work_record *work,
  4299. +                       char *name,int servertype, 
  4300. +                       int ttl,char *comment,
  4301. +                       BOOL replace)
  4302. +{
  4303. +  BOOL newentry=False;
  4304. +  struct server_record *s;
  4305. +  
  4306. +  if (name[0] == '*')
  4307. +  {
  4308. +      return (NULL);
  4309. +  }
  4310. +  
  4311. +  s = find_server(work, name);
  4312. +
  4313. +  if (s && !replace)
  4314. +  {
  4315. +    DEBUG(4,("Not replacing %s\n",name));
  4316. +    return(s);
  4317. +  }
  4318. +  
  4319. +  if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
  4320. +    updatedlists=True;
  4321. +
  4322. +  if (!s)
  4323. +  {
  4324. +    newentry = True;
  4325. +    s = (struct server_record *)malloc(sizeof(*s));
  4326. +      
  4327. +    if (!s) return(NULL);
  4328. +      
  4329. +    bzero((char *)s,sizeof(*s));
  4330. +  }
  4331. +  
  4332. +  
  4333. +  if (d->my_interface && strequal(lp_workgroup(),work->work_group))
  4334. +    {
  4335. +      if (servertype)
  4336. +        servertype |= SV_TYPE_LOCAL_LIST_ONLY;
  4337. +    }
  4338. +  else
  4339. +    {
  4340. +      servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
  4341. +    }
  4342. +  
  4343. +  /* update the entry */
  4344. +  StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
  4345. +  StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
  4346. +  strupper(s->serv.name);
  4347. +  s->serv.type  = servertype;
  4348. +  s->death_time = servertype ? (ttl?time(NULL)+ttl*3:0) : (time(NULL)-1);
  4349. +  
  4350. +  /* for a domain entry, the comment field refers to the server name */
  4351. +  
  4352. +  if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
  4353. +  
  4354. +  if (newentry)
  4355. +    {
  4356. +      add_server(work, s);
  4357. +      
  4358. +      DEBUG(3,("Added "));
  4359. +    }
  4360. +  else
  4361. +    {
  4362. +      DEBUG(3,("Updated "));
  4363. +    }
  4364. +  
  4365. +  DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
  4366. +       name,servertype,comment,
  4367. +       work->work_group,inet_ntoa(d->bcast_ip)));
  4368. +  
  4369. +  return(s);
  4370. +}
  4371. +
  4372. +
  4373. +/*******************************************************************
  4374. +  expire old servers in the serverlist
  4375. +  ******************************************************************/
  4376. +void expire_servers(time_t t)
  4377. +{
  4378. +  struct subnet_record *d;
  4379. +  
  4380. +  for (d = subnetlist ; d ; d = d->next)
  4381. +    {
  4382. +      struct work_record *work;
  4383. +      
  4384. +      for (work = d->workgrouplist; work; work = work->next)
  4385. +    {
  4386. +      remove_old_servers(work, t, False);
  4387. +    }
  4388. +    }
  4389. +}
  4390. +
  4391. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbsubnet.c samba-1.9.16alpha11/source/namedbsubnet.c
  4392. --- samba-1.9.16alpha10/source/namedbsubnet.c    Thu Jan  1 10:00:00 1970
  4393. +++ samba-1.9.16alpha11/source/namedbsubnet.c    Thu Jul 11 04:48:26 1996
  4394. @@ -0,0 +1,346 @@
  4395. +/* 
  4396. +   Unix SMB/Netbios implementation.
  4397. +   Version 1.9.
  4398. +   NBT netbios routines and daemon - version 2
  4399. +   Copyright (C) Andrew Tridgell 1994-1996
  4400. +   
  4401. +   This program is free software; you can redistribute it and/or modify
  4402. +   it under the terms of the GNU General Public License as published by
  4403. +   the Free Software Foundation; either version 2 of the License, or
  4404. +   (at your option) any later version.
  4405. +   
  4406. +   This program is distributed in the hope that it will be useful,
  4407. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  4408. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4409. +   GNU General Public License for more details.
  4410. +   
  4411. +   You should have received a copy of the GNU General Public License
  4412. +   along with this program; if not, write to the Free Software
  4413. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4414. +   
  4415. +   Revision History:
  4416. +
  4417. +   14 jan 96: lkcl@pires.co.uk
  4418. +   added multiple workgroup domain master support
  4419. +
  4420. +   04 jul 96: lkcl@pires.co.uk
  4421. +   created module namedbsubnet containing subnet database functions
  4422. +
  4423. +*/
  4424. +
  4425. +#include "includes.h"
  4426. +#include "smb.h"
  4427. +
  4428. +extern int ClientNMB;
  4429. +extern int ClientDGRAM;
  4430. +
  4431. +extern int DEBUGLEVEL;
  4432. +
  4433. +extern struct in_addr ipgrp;
  4434. +extern struct in_addr ipzero;
  4435. +
  4436. +extern pstring myname;
  4437. +
  4438. +BOOL updatedlists = True;
  4439. +int updatecount = 0;
  4440. +
  4441. +/* local interfaces structure */
  4442. +extern struct interface *local_interfaces;
  4443. +
  4444. +/* remote interfaces structure */
  4445. +extern struct interface *remote_interfaces;
  4446. +
  4447. +/* this is our domain/workgroup/server database */
  4448. +struct subnet_record *subnetlist = NULL;
  4449. +
  4450. +
  4451. +/****************************************************************************
  4452. +  add a domain into the list
  4453. +  **************************************************************************/
  4454. +static void add_subnet(struct subnet_record *d)
  4455. +{
  4456. +  struct subnet_record *d2;
  4457. +
  4458. +  if (!subnetlist)
  4459. +  {
  4460. +    subnetlist = d;
  4461. +    d->prev = NULL;
  4462. +    d->next = NULL;
  4463. +    return;
  4464. +  }
  4465. +
  4466. +  for (d2 = subnetlist; d2->next; d2 = d2->next);
  4467. +
  4468. +  d2->next = d;
  4469. +  d->next = NULL;
  4470. +  d->prev = d2;
  4471. +}
  4472. +
  4473. +
  4474. +/****************************************************************************
  4475. +  find a subnet in the subnetlist 
  4476. +  **************************************************************************/
  4477. +struct subnet_record *find_subnet(struct in_addr bcast_ip)
  4478. +{   
  4479. +  struct subnet_record *d;
  4480. +  struct in_addr wins_ip = ipgrp;
  4481. +  
  4482. +  /* search through subnet list for broadcast/netmask that matches
  4483. +     the source ip address. a subnet 255.255.255.255 represents the
  4484. +     WINS list. */
  4485. +  
  4486. +  for (d = subnetlist; d; d = d->next)
  4487. +    {
  4488. +        if (ip_equal(bcast_ip, wins_ip))
  4489. +        {
  4490. +           if (ip_equal(bcast_ip, d->bcast_ip))
  4491. +           {
  4492. +               return d;
  4493. +           }
  4494. +        }
  4495. +        else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
  4496. +        {
  4497. +          return(d);
  4498. +        }
  4499. +    }
  4500. +  
  4501. +  return (NULL);
  4502. +}
  4503. +
  4504. +
  4505. +/****************************************************************************
  4506. +  finds the appropriate subnet structure. directed packets (non-bcast) are
  4507. +  assumed to come from a point-to-point (P or M node), and so the subnet we
  4508. +  return in this instance is the WINS 'pseudo-subnet' with ip 255.255.255.255
  4509. +  ****************************************************************************/
  4510. +struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast)
  4511. +{
  4512. +  if (bcast)
  4513. +  {
  4514. +    /* identify the subnet the broadcast request came from */
  4515. +    return find_subnet(*iface_bcast(ip));
  4516. +  }
  4517. +  /* find the subnet under the pseudo-ip of 255.255.255.255 */
  4518. +  return find_subnet(ipgrp);
  4519. +}
  4520. +
  4521. +
  4522. +/****************************************************************************
  4523. +  create a domain entry
  4524. +  ****************************************************************************/
  4525. +static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr mask_ip)
  4526. +{
  4527. +  struct subnet_record *d;
  4528. +  d = (struct subnet_record *)malloc(sizeof(*d));
  4529. +  
  4530. +  if (!d) return(NULL);
  4531. +  
  4532. +  bzero((char *)d,sizeof(*d));
  4533. +  
  4534. +  DEBUG(4, ("making domain %s ", inet_ntoa(bcast_ip)));
  4535. +  DEBUG(4, ("%s\n", inet_ntoa(mask_ip)));
  4536. +  
  4537. +  d->bcast_ip = bcast_ip;
  4538. +  d->mask_ip  = mask_ip;
  4539. +  d->workgrouplist = NULL;
  4540. +  d->my_interface = False; /* True iff the interface is on the samba host */
  4541. +  
  4542. +  add_subnet(d);
  4543. +  
  4544. +  return d;
  4545. +}
  4546. +
  4547. +
  4548. +/****************************************************************************
  4549. +  add the remote interfaces from lp_remote_interfaces() and lp_interfaces()
  4550. +  to the netbios subnet database.
  4551. +  ****************************************************************************/
  4552. +void add_subnet_interfaces(void)
  4553. +{
  4554. +    struct interface *i;
  4555. +
  4556. +    /* loop on all local interfaces */
  4557. +    for (i = local_interfaces; i; i = i->next)
  4558. +    {
  4559. +        /* add the interface into our subnet database */
  4560. +        if (!find_subnet(i->bcast))
  4561. +        {
  4562. +            struct subnet_record *d = make_subnet(i->bcast,i->nmask);
  4563. +            if (d)
  4564. +            {
  4565. +                /* short-cut method to identifying local interfaces */
  4566. +                d->my_interface = True;
  4567. +            }
  4568. +        }
  4569. +    }
  4570. +
  4571. +    /* loop on all remote interfaces */
  4572. +    for (i = remote_interfaces; i; i = i->next)
  4573. +    {
  4574. +        /* add the interface into our subnet database */
  4575. +        if (!find_subnet(i->bcast))
  4576. +        {
  4577. +            make_subnet(i->bcast,i->nmask);
  4578. +        }
  4579. +    }
  4580. +
  4581. +    /* add the pseudo-ip interface for WINS: 255.255.255.255 */
  4582. +    if (lp_wins_support())
  4583. +    {
  4584. +        struct in_addr wins_bcast = ipgrp;
  4585. +        struct in_addr wins_nmask = ipzero;
  4586. +        make_subnet(wins_bcast, wins_nmask);
  4587. +    }
  4588. +}
  4589. +
  4590. +
  4591. +
  4592. +/****************************************************************************
  4593. +  add the default workgroup into my domain
  4594. +  **************************************************************************/
  4595. +void add_my_subnets(char *group)
  4596. +{
  4597. +  struct interface *i;
  4598. +
  4599. +  /* add or find domain on our local subnet, in the default workgroup */
  4600. +  
  4601. +  if (*group == '*') return;
  4602. +
  4603. +    /* the coding choice is up to you, andrew: i can see why you don't want
  4604. +       global access to the local_interfaces structure: so it can't get
  4605. +       messed up! */
  4606. +    for (i = local_interfaces; i; i = i->next)
  4607. +    {
  4608. +      add_subnet_entry(i->bcast,i->nmask,group, True, False);
  4609. +    }
  4610. +}
  4611. +
  4612. +
  4613. +/****************************************************************************
  4614. +  add a domain entry. creates a workgroup, if necessary, and adds the domain
  4615. +  to the named a workgroup.
  4616. +  ****************************************************************************/
  4617. +struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, 
  4618. +                       struct in_addr mask_ip,
  4619. +                       char *name, BOOL add, BOOL lmhosts)
  4620. +{
  4621. +  struct subnet_record *d;
  4622. +
  4623. +  /* XXXX andrew: struct in_addr ip appears not to be referenced at all except
  4624. +     in the DEBUG comment. i assume that the DEBUG comment below actually
  4625. +     intends to refer to bcast_ip? i don't know.
  4626. +
  4627. +  struct in_addr ip = ipgrp;
  4628. +
  4629. +  */
  4630. +
  4631. +  if (zero_ip(bcast_ip)) 
  4632. +    bcast_ip = *iface_bcast(bcast_ip);
  4633. +  
  4634. +  /* add the domain into our domain database */
  4635. +  if ((d = find_subnet(bcast_ip)) ||
  4636. +      (d = make_subnet(bcast_ip, mask_ip)))
  4637. +    {
  4638. +      struct work_record *w = find_workgroupstruct(d, name, add);
  4639. +      extern pstring ServerComment;
  4640. +      
  4641. +      if (!w) return NULL;
  4642. +
  4643. +      /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
  4644. +     or register with WINS server, if it's our workgroup */
  4645. +      if (strequal(lp_workgroup(), name) && d->my_interface)
  4646. +    {
  4647. +      add_my_name_entry(d,name,0x1e,NB_ACTIVE|NB_GROUP);
  4648. +      add_my_name_entry(d,name,0x0 ,NB_ACTIVE|NB_GROUP);
  4649. +    }
  4650. +      /* add samba server name to workgroup list. don't add
  4651. +         lmhosts server entries to local interfaces */
  4652. +      if ((strequal(lp_workgroup(), name) && d->my_interface) ||
  4653. +          (lmhosts && !d->my_interface))
  4654. +      {
  4655. +        add_server_entry(d,w,myname,w->ServerType,0,ServerComment,True);
  4656. +        DEBUG(3,("Added server name entry %s at %s\n",
  4657. +                  name,inet_ntoa(bcast_ip)));
  4658. +      }
  4659. +      
  4660. +      return d;
  4661. +    }
  4662. +  return NULL;
  4663. +}
  4664. +
  4665. +
  4666. +/*******************************************************************
  4667. +  write out browse.dat
  4668. +  ******************************************************************/
  4669. +void write_browse_list(void)
  4670. +{
  4671. +  struct subnet_record *d;
  4672. +  pstring fname,fnamenew;
  4673. +  FILE *f;
  4674. +
  4675. +  static time_t lasttime = 0;
  4676. +  time_t t = time(NULL);
  4677. +
  4678. +  if (!lasttime) lasttime = t;
  4679. +  if (!updatedlists || t - lasttime < 5) return;
  4680. +  
  4681. +  lasttime = t;
  4682. +  updatedlists = False;
  4683. +  updatecount++;
  4684. +  
  4685. +  dump_names();
  4686. +  dump_workgroups();
  4687. +  
  4688. +  strcpy(fname,lp_lockdir());
  4689. +  trim_string(fname,NULL,"/");
  4690. +  strcat(fname,"/");
  4691. +  strcat(fname,SERVER_LIST);
  4692. +  strcpy(fnamenew,fname);
  4693. +  strcat(fnamenew,".");
  4694. +  
  4695. +  f = fopen(fnamenew,"w");
  4696. +  
  4697. +  if (!f)
  4698. +    {
  4699. +      DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
  4700. +      return;
  4701. +    }
  4702. +  
  4703. +  for (d = subnetlist; d ; d = d->next)
  4704. +    {
  4705. +      struct work_record *work;
  4706. +      for (work = d->workgrouplist; work ; work = work->next)
  4707. +    {
  4708. +      struct server_record *s;
  4709. +      for (s = work->serverlist; s ; s = s->next)
  4710. +        {
  4711. +          fstring tmp;
  4712. +          
  4713. +          /* don't list domains I don't have a master for */
  4714. +          if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) && !s->serv.comment[0])
  4715. +        {
  4716. +          continue;
  4717. +        }
  4718. +          
  4719. +          /* output server details, plus what workgroup/domain
  4720. +         they're in. without the domain information, the
  4721. +         combined list of all servers in all workgroups gets
  4722. +         sent to anyone asking about any workgroup! */
  4723. +          
  4724. +          sprintf(tmp, "\"%s\"", s->serv.name);
  4725. +          fprintf(f, "%-25s ", tmp);
  4726. +          fprintf(f, "%08x ", s->serv.type);
  4727. +          sprintf(tmp, "\"%s\" ", s->serv.comment);
  4728. +          fprintf(f, "%-30s", tmp);
  4729. +          fprintf(f, "\"%s\"\n", work->work_group);
  4730. +        }
  4731. +    }
  4732. +    }
  4733. +  
  4734. +  fclose(f);
  4735. +  unlink(fname);
  4736. +  chmod(fnamenew,0644);
  4737. +  rename(fnamenew,fname);   
  4738. +  DEBUG(3,("Wrote browse list %s\n",fname));
  4739. +}
  4740. +
  4741. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namedbwork.c samba-1.9.16alpha11/source/namedbwork.c
  4742. --- samba-1.9.16alpha10/source/namedbwork.c    Thu Jan  1 10:00:00 1970
  4743. +++ samba-1.9.16alpha11/source/namedbwork.c    Wed Jul 10 04:01:25 1996
  4744. @@ -0,0 +1,255 @@
  4745. +/* 
  4746. +   Unix SMB/Netbios implementation.
  4747. +   Version 1.9.
  4748. +   NBT netbios routines and daemon - version 2
  4749. +   Copyright (C) Andrew Tridgell 1994-1996
  4750. +   
  4751. +   This program is free software; you can redistribute it and/or modify
  4752. +   it under the terms of the GNU General Public License as published by
  4753. +   the Free Software Foundation; either version 2 of the License, or
  4754. +   (at your option) any later version.
  4755. +   
  4756. +   This program is distributed in the hope that it will be useful,
  4757. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  4758. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4759. +   GNU General Public License for more details.
  4760. +   
  4761. +   You should have received a copy of the GNU General Public License
  4762. +   along with this program; if not, write to the Free Software
  4763. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4764. +   
  4765. +   Revision History:
  4766. +
  4767. +   14 jan 96: lkcl@pires.co.uk
  4768. +   added multiple workgroup domain master support
  4769. +
  4770. +   04 jul 96: lkcl@pires.co.uk
  4771. +   created module namedbwork containing workgroup database functions
  4772. +
  4773. +*/
  4774. +
  4775. +#include "includes.h"
  4776. +#include "smb.h"
  4777. +
  4778. +extern int ClientNMB;
  4779. +
  4780. +extern int DEBUGLEVEL;
  4781. +
  4782. +/* this is our domain/workgroup/server database */
  4783. +extern struct subnet_record *subnetlist;
  4784. +
  4785. +int workgroup_count = 0; /* unique index key: one for each workgroup */
  4786. +
  4787. +/* what server type are we currently */
  4788. +
  4789. +#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
  4790. +            SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
  4791. +            SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
  4792. +
  4793. +
  4794. +/****************************************************************************
  4795. +  add a workgroup into the domain list
  4796. +  **************************************************************************/
  4797. +static void add_workgroup(struct work_record *work, struct subnet_record *d)
  4798. +{
  4799. +  struct work_record *w2;
  4800. +
  4801. +  if (!work || !d) return;
  4802. +
  4803. +  if (!d->workgrouplist)
  4804. +    {
  4805. +      d->workgrouplist = work;
  4806. +      work->prev = NULL;
  4807. +      work->next = NULL;
  4808. +      return;
  4809. +    }
  4810. +  
  4811. +  for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
  4812. +  
  4813. +  w2->next = work;
  4814. +  work->next = NULL;
  4815. +  work->prev = w2;
  4816. +}
  4817. +
  4818. +
  4819. +/****************************************************************************
  4820. +  create a blank workgroup 
  4821. +  **************************************************************************/
  4822. +static struct work_record *make_workgroup(char *name)
  4823. +{
  4824. +  struct work_record *work;
  4825. +  struct subnet_record *d;
  4826. +  int t = -1;
  4827. +  
  4828. +  if (!name || !name[0]) return NULL;
  4829. +  
  4830. +  work = (struct work_record *)malloc(sizeof(*work));
  4831. +  if (!work) return(NULL);
  4832. +  
  4833. +  StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
  4834. +  work->serverlist = NULL;
  4835. +  
  4836. +  work->ServerType = DFLT_SERVER_TYPE;
  4837. +  work->RunningElection = False;
  4838. +  work->ElectionCount = 0;
  4839. +  work->needelection = False;
  4840. +  work->needannounce = True;
  4841. +  work->state = MST_NONE;
  4842. +  
  4843. +  /* make sure all token representations of workgroups are unique */
  4844. +  
  4845. +  for (d = subnetlist; d && t == -1; d = d->next)
  4846. +    {
  4847. +      struct work_record *w;
  4848. +      for (w = d->workgrouplist; w && t == -1; w = w->next)
  4849. +    {
  4850. +      if (strequal(w->work_group, work->work_group)) t = w->token;
  4851. +    }
  4852. +    }
  4853. +  
  4854. +  if (t == -1)
  4855. +    {
  4856. +      work->token = ++workgroup_count;
  4857. +    }
  4858. +  else
  4859. +    {
  4860. +      work->token = t;
  4861. +    }
  4862. +  
  4863. +  
  4864. +  /* WfWg  uses 01040b01 */
  4865. +  /* Win95 uses 01041501 */
  4866. +  /* NTAS  uses ???????? */
  4867. +  work->ElectionCriterion  = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8); 
  4868. +  work->ElectionCriterion |= (lp_os_level() << 24);
  4869. +  if (lp_domain_master()) {
  4870. +    work->ElectionCriterion |= 0x80;
  4871. +  }
  4872. +  
  4873. +  return work;
  4874. +}
  4875. +
  4876. +
  4877. +/*******************************************************************
  4878. +  remove workgroups
  4879. +  ******************************************************************/
  4880. +struct work_record *remove_workgroup(struct subnet_record *d, 
  4881. +                     struct work_record *work,
  4882. +                     BOOL remove_all_servers)
  4883. +{
  4884. +  struct work_record *ret_work = NULL;
  4885. +  
  4886. +  if (!d || !work) return NULL;
  4887. +  
  4888. +  DEBUG(3,("Removing old workgroup %s\n", work->work_group));
  4889. +  
  4890. +  ret_work = work->next;
  4891. +
  4892. +  remove_old_servers(work, -1, remove_all_servers);
  4893. +  
  4894. +  if (!work->serverlist)
  4895. +  {
  4896. +    if (work->prev) work->prev->next = work->next;
  4897. +    if (work->next) work->next->prev = work->prev;
  4898. +  
  4899. +    if (d->workgrouplist == work) d->workgrouplist = work->next; 
  4900. +  
  4901. +    free(work);
  4902. +  }
  4903. +  
  4904. +  return ret_work;
  4905. +}
  4906. +
  4907. +
  4908. +/****************************************************************************
  4909. +  find a workgroup in the workgrouplist 
  4910. +  only create it if the domain allows it, or the parameter 'add' insists
  4911. +  that it get created/added anyway. this allows us to force entries in
  4912. +  lmhosts file to be added.
  4913. +  **************************************************************************/
  4914. +struct work_record *find_workgroupstruct(struct subnet_record *d, 
  4915. +                     fstring name, BOOL add)
  4916. +{
  4917. +  struct work_record *ret, *work;
  4918. +  
  4919. +  if (!d) return NULL;
  4920. +  
  4921. +  DEBUG(4, ("workgroup search for %s: ", name));
  4922. +  
  4923. +  if (strequal(name, "*"))
  4924. +    {
  4925. +      DEBUG(2,("add any workgroups: initiating browser search on %s\n",
  4926. +           inet_ntoa(d->bcast_ip)));
  4927. +      queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY, NAME_QUERY_FIND_MST,
  4928. +                 MSBROWSE,0x1,0,0,
  4929. +                 True,False, d->bcast_ip, d->bcast_ip);
  4930. +      return NULL;
  4931. +    }
  4932. +  
  4933. +  for (ret = d->workgrouplist; ret; ret = ret->next) {
  4934. +    if (!strcmp(ret->work_group,name)) {
  4935. +      DEBUG(4, ("found\n"));
  4936. +      return(ret);
  4937. +    }
  4938. +  }
  4939. +
  4940. +  if (!add) {
  4941. +    DEBUG(4, ("not found\n"));
  4942. +    return NULL;
  4943. +  }
  4944. +
  4945. +  DEBUG(4,("not found: creating\n"));
  4946. +  
  4947. +  if ((work = make_workgroup(name)))
  4948. +    {
  4949. +      if (lp_preferred_master() &&
  4950. +      strequal(lp_workgroup(), name) &&
  4951. +      d->my_interface)
  4952. +    {
  4953. +      DEBUG(3, ("preferred master startup for %s\n", work->work_group));
  4954. +      work->needelection = True;
  4955. +      work->ElectionCriterion |= (1<<3);
  4956. +    }
  4957. +      if (!d->my_interface)
  4958. +    {
  4959. +      work->needelection = False;
  4960. +    }
  4961. +      add_workgroup(work, d);
  4962. +      return(work);
  4963. +    }
  4964. +  return NULL;
  4965. +}
  4966. +
  4967. +
  4968. +/****************************************************************************
  4969. +  dump a copy of the workgroup/domain database
  4970. +  **************************************************************************/
  4971. +void dump_workgroups(void)
  4972. +{
  4973. +  struct subnet_record *d;
  4974. +  
  4975. +  for (d = subnetlist; d; d = d->next)
  4976. +    {
  4977. +      if (d->workgrouplist)
  4978. +    {
  4979. +      struct work_record *work;
  4980. +      
  4981. +      DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
  4982. +      DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
  4983. +      
  4984. +      for (work = d->workgrouplist; work; work = work->next)
  4985. +        {
  4986. +          DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
  4987. +          if (work->serverlist)
  4988. +        {
  4989. +          struct server_record *s;          
  4990. +          for (s = work->serverlist; s; s = s->next)
  4991. +            {
  4992. +              DEBUG(4,("\t\t%s %8x (%s)\n",
  4993. +                   s->serv.name, s->serv.type, s->serv.comment));
  4994. +            }
  4995. +        }
  4996. +        }
  4997. +    }
  4998. +    }
  4999. +}
  5000. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameelect.c samba-1.9.16alpha11/source/nameelect.c
  5001. --- samba-1.9.16alpha10/source/nameelect.c    Mon Jun 10 15:18:56 1996
  5002. +++ samba-1.9.16alpha11/source/nameelect.c    Thu Jul 18 20:53:15 1996
  5003. @@ -2,7 +2,7 @@
  5004.     Unix SMB/Netbios implementation.
  5005.     Version 1.9.
  5006.     NBT netbios routines and daemon - version 2
  5007. -   Copyright (C) Andrew Tridgell 1994-1995
  5008. +   Copyright (C) Andrew Tridgell 1994-1996
  5009.     
  5010.     This program is free software; you can redistribute it and/or modify
  5011.     it under the terms of the GNU General Public License as published by
  5012. @@ -18,11 +18,17 @@
  5013.     along with this program; if not, write to the Free Software
  5014.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  5015.     
  5016. +   Module name: nameelect.c
  5017. +
  5018.     Revision History:
  5019.  
  5020.     14 jan 96: lkcl@pires.co.uk
  5021.     added multiple workgroup domain master support
  5022.  
  5023. +   04 jul 96: lkcl@pires.co.uk
  5024. +   added system to become a master browser by stages.
  5025. +
  5026. +
  5027.  */
  5028.  
  5029.  #include "includes.h"
  5030. @@ -34,6 +40,8 @@
  5031.  extern pstring scope;
  5032.  
  5033.  extern pstring myname;
  5034. +extern struct in_addr ipzero;
  5035. +extern struct in_addr ipgrp;
  5036.  
  5037.  /* machine comment for host announcements */
  5038.  extern  pstring ServerComment;
  5039. @@ -42,10 +50,6 @@
  5040.  
  5041.  extern time_t StartupTime;
  5042.  
  5043. -#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
  5044. -
  5045. -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
  5046. -
  5047.  extern struct subnet_record *subnetlist;
  5048.  
  5049.  
  5050. @@ -59,9 +63,8 @@
  5051.    struct subnet_record *d;
  5052.  
  5053.    if (!lastrun) lastrun = t;
  5054. -  if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) 
  5055. +  if (t < lastrun + CHECK_TIME_MST_BROWSE * 60)
  5056.      return;
  5057. -
  5058.    lastrun = t;
  5059.  
  5060.    dump_workgroups();
  5061. @@ -77,9 +80,9 @@
  5062.  
  5063.        if (!AM_MASTER(work))
  5064.          {
  5065. -          queue_netbios_packet(ClientNMB,NMB_QUERY,CHECK_MASTER,
  5066. -                   work->work_group,0x1d,0,
  5067. -                   True,False,d->bcast_ip);
  5068. +          queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
  5069. +                   work->work_group,0x1d,0,0,
  5070. +                   True,False,d->bcast_ip,d->bcast_ip);
  5071.          }
  5072.      }
  5073.      }
  5074. @@ -91,36 +94,38 @@
  5075.    ******************************************************************/
  5076.  void browser_gone(char *work_name, struct in_addr ip)
  5077.  {
  5078. -  struct subnet_record *d = find_domain(ip);
  5079. +  struct subnet_record *d = find_subnet(ip);
  5080.    struct work_record *work = find_workgroupstruct(d, work_name, False);
  5081.  
  5082. +  /* i don't know about this workgroup, therefore i don't care */
  5083.    if (!work || !d) return;
  5084. -
  5085. -  if (strequal(work->work_group, lp_workgroup()) &&
  5086. -      d->my_interface)
  5087. -    {
  5088. +  if (strequal(work->work_group, lp_workgroup()) && d->my_interface)
  5089. +  {
  5090.  
  5091.        DEBUG(2,("Forcing election on %s %s\n",
  5092.             work->work_group,inet_ntoa(d->bcast_ip)));
  5093.  
  5094.        /* we can attempt to become master browser */
  5095.        work->needelection = True;
  5096. -    }
  5097. +  }
  5098.    else
  5099. -    {
  5100. -      /* XXXX note: this will delete entries that have been added in by
  5101. -     lmhosts as well. a flag to ensure that these are not deleted may
  5102. -     be considered */
  5103. -      
  5104. -      /* workgroup with no master browser is not the default workgroup:
  5105. -     it's also not on our subnet. therefore delete it: it can be
  5106. -     recreated dynamically */
  5107. -      
  5108. -      send_election(d, work->work_group, 0, 0, myname);
  5109. -      remove_workgroup(d, work);      
  5110. -    }
  5111. +  {
  5112. +     /* local interfaces: force an election */
  5113. +     if (d->my_interface)
  5114. +       send_election(d, work->work_group, 0, 0, myname);
  5115. +
  5116. +     /* only removes workgroup completely on a local interface or
  5117. +        if there are no server entries on the remote interface.
  5118. +        (persistent lmhost entries on a remote interface will stop
  5119. +        the workgroup being removed. persistent lmhosts entries on
  5120. +        a local interface _will_ be removed).
  5121. +      */
  5122. +     remove_workgroup(d, work, d->my_interface);      
  5123. +  }
  5124.  }
  5125.  
  5126. +
  5127.  /****************************************************************************
  5128.    send an election packet
  5129.    **************************************************************************/
  5130. @@ -137,7 +142,7 @@
  5131.  
  5132.    bzero(outbuf,sizeof(outbuf));
  5133.    p = outbuf;
  5134. -  CVAL(p,0) = 8; /* election */
  5135. +  CVAL(p,0) = ANN_Election; /* election */
  5136.    p++;
  5137.  
  5138.    CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
  5139. @@ -153,68 +158,318 @@
  5140.  }
  5141.  
  5142.  
  5143. +/****************************************************************************
  5144. +  un-register a SELF name that got rejected.
  5145. +
  5146. +  if this name happens to be rejected when samba is in the process
  5147. +  of becoming a master browser (registering __MSBROWSE__, WORKGROUP(1d)
  5148. +  or WORKGROUP(1b)) then we must stop being a master browser. sad.
  5149. +
  5150. +  **************************************************************************/
  5151. +void name_unregister_work(struct subnet_record *d, char *name, int name_type)
  5152. +{
  5153. +    struct work_record *work;
  5154. +
  5155. +    remove_netbios_name(d,name,name_type,SELF,ipzero);
  5156. +
  5157. +    if (!(work = find_workgroupstruct(d, name, False))) return;
  5158. +
  5159. +    if (ms_browser_name(name, name_type) ||
  5160. +        (AM_MASTER(work) && strequal(name, lp_workgroup()) == 0 &&
  5161. +         (name_type == 0x1d || name_type == 0x1b)))
  5162. +    {
  5163. +      int remove_type = 0;
  5164. +
  5165. +      if (ms_browser_name(name, name_type))
  5166. +        remove_type = SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER;
  5167. +      if (name_type == 0x1d)
  5168. +        remove_type = SV_TYPE_MASTER_BROWSER;
  5169. +      if (name_type == 0x1b)
  5170. +        remove_type = SV_TYPE_DOMAIN_MASTER;
  5171. +            
  5172. +      become_nonmaster(d, work, remove_type);
  5173. +    }
  5174. +}
  5175. +
  5176. +
  5177. +/****************************************************************************
  5178. +  registers a name.
  5179. +
  5180. +  if the name being added is a SELF name, we must additionally check
  5181. +  whether to proceed to the next stage in samba becoming a master browser.
  5182. +
  5183. +  **************************************************************************/
  5184. +void name_register_work(struct subnet_record *d, char *name, int name_type,
  5185. +                int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
  5186. +{
  5187. +  enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
  5188. +                                SELF : REGISTER;
  5189. +
  5190. +  if (source == SELF)
  5191. +  {
  5192. +    struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
  5193. +
  5194. +    add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
  5195. +
  5196. +    if (work)
  5197. +    {
  5198. +      if (work->state != MST_NONE)
  5199. +      {
  5200. +        /* samba is in the process of working towards master browser-ness.
  5201. +           initiate the next stage.
  5202. +         */
  5203. +        become_master(d, work);
  5204. +        return;
  5205. +      }
  5206. +    }
  5207. +  }
  5208. +}
  5209. +
  5210. +
  5211.  /*******************************************************************
  5212. -  become the master browser
  5213. +  become the master browser.
  5214. +
  5215. +  this is done in stages. note that this could take a while, 
  5216. +  particularly on a broadcast subnet, as we have to wait for
  5217. +  the implicit registration of each name to be accepted.
  5218. +
  5219. +  as each name is successfully registered, become_master() is
  5220. +  called again, in order to initiate the next stage. see
  5221. +  dead_netbios_entry() - deals with implicit name registration
  5222. +  and response_name_reg() - deals with explicit registration
  5223. +  with a WINS server.
  5224. +
  5225. +  stage 1: was MST_NONE - go to MST_NONE and register ^1^2__MSBROWSE__^2^1.
  5226. +  stage 2: was MST_WON  - go to MST_MSB  and register WORKGROUP(0x1d)
  5227. +  stage 3: was MST_MSB  - go to MST_BROWSER and register WORKGROUP(0x1b)
  5228. +  stage 4: was MST_BROWSER - go to MST_DOMAIN (do not pass GO, do not...)
  5229. +
  5230. +  XXXX note: this code still does not cope with the distinction
  5231. +  between different types of nodes, particularly between M and P
  5232. +  nodes. that comes later.
  5233. +
  5234.    ******************************************************************/
  5235. -static void become_master(struct subnet_record *d, struct work_record *work)
  5236. +void become_master(struct subnet_record *d, struct work_record *work)
  5237.  {
  5238. -  uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX | 0x00400000;
  5239. +  uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX|0x00400000;
  5240.  
  5241.    if (!work) return;
  5242.    
  5243. -  DEBUG(2,("Becoming master for %s\n",work->work_group));
  5244. +  DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
  5245. +                    work->work_group,inet_ntoa(d->bcast_ip),work->state));
  5246.    
  5247. -  work->ServerType |= SV_TYPE_MASTER_BROWSER;
  5248. -  work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
  5249. -  work->ElectionCriterion |= 0x5;
  5250. +  switch (work->state)
  5251. +  {
  5252. +    case MST_NONE: /* while we were nothing but a server... */
  5253. +    {
  5254. +      DEBUG(3,("go to first stage: register ^1^2__MSBROWSE__^2^1\n"));
  5255. +      work->state = MST_WON; /* ... an election win was successful */
  5256. +
  5257. +      work->ElectionCriterion |= 0x5;
  5258. +
  5259. +      /* update our server status */
  5260. +      work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
  5261. +      add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
  5262. +
  5263. +      /* add special browser name */
  5264. +      add_my_name_entry(d,MSBROWSE        ,0x01,NB_ACTIVE|NB_GROUP);
  5265. +
  5266. +      /* DON'T do anything else after calling add_my_name_entry() */
  5267. +      return;
  5268. +    }
  5269. +    case MST_WON: /* while nothing had happened except we won an election... */
  5270. +    {
  5271. +      DEBUG(3,("go to second stage: register as master browser\n"));
  5272. +      work->state = MST_MSB; /* ... registering MSBROWSE was successful */
  5273. +
  5274. +      /* add server entry on successful registration of MSBROWSE */
  5275. +      add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
  5276. +
  5277. +      /* add master name */
  5278. +      add_my_name_entry(d,work->work_group,0x1d,NB_ACTIVE         );
  5279.    
  5280. -  /* add browse, master and general names to database or register with WINS */
  5281. -  add_name_entry(MSBROWSE        ,0x01,NB_ACTIVE|NB_GROUP);
  5282. -  add_name_entry(work->work_group,0x1d,NB_ACTIVE         );
  5283. +      /* DON'T do anything else after calling add_my_name_entry() */
  5284. +      return;
  5285. +    }
  5286. +    case MST_MSB: /* while we were still only registered MSBROWSE state... */
  5287. +    {
  5288. +      DEBUG(3,("2nd stage complete: registered as master browser\n"));
  5289. +      work->state = MST_BROWSER; /* ... registering WORKGROUP(1d) succeeded */
  5290. +
  5291. +      /* update our server status */
  5292. +      work->ServerType |= SV_TYPE_MASTER_BROWSER;
  5293. +      add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
  5294. +
  5295. +      if (d->my_interface && work->serverlist == NULL) /* no servers! */
  5296. +      {
  5297. +        /* ask all servers on our local net to announce to us */
  5298. +        announce_request(work, d->bcast_ip);
  5299. +      }
  5300. +      break;
  5301. +   }
  5302. +
  5303. +   case MST_BROWSER:
  5304. +   {
  5305. +      /* don't have to do anything: just report success */
  5306. +      DEBUG(3,("3rd stage: become master browser!\n"));
  5307. +
  5308. +      break;
  5309. +   }
  5310. +
  5311. +   case MST_DOMAIN_NONE:
  5312. +   {
  5313. +      if (lp_domain_master())
  5314. +      {
  5315. +        work->state = MST_DOMAIN_MEM; /* ... become domain member */
  5316. +        DEBUG(3,("domain first stage: register as domain member\n"));
  5317. +
  5318. +        /* add domain member name */
  5319. +        add_my_name_entry(d,work->work_group,0x1e,NB_ACTIVE         );
  5320. +
  5321. +        /* DON'T do anything else after calling add_my_name_entry() */
  5322. +        return;
  5323. +      }
  5324. +      else
  5325. +      {
  5326. +        DEBUG(4,("samba not configured as a domain master.\n"));
  5327. +      }
  5328. +  
  5329. +      break;
  5330. +   }
  5331. +
  5332. +   case MST_DOMAIN_MEM:
  5333. +   {
  5334. +      if (lp_domain_master())
  5335. +      {
  5336. +        work->state = MST_DOMAIN_TST; /* ... possibly become domain master */
  5337. +        DEBUG(3,("domain second stage: register as domain master\n"));
  5338. +
  5339. +        if (lp_domain_logons())
  5340. +        {
  5341. +          work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
  5342. +          add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
  5343. +        }
  5344. +
  5345. +        /* add domain master name */
  5346. +        add_my_name_entry(d,work->work_group,0x1b,NB_ACTIVE         );
  5347. +
  5348. +        /* DON'T do anything else after calling add_my_name_entry() */
  5349. +        return;
  5350. +      }
  5351. +      else
  5352. +      {
  5353. +        DEBUG(4,("samba not configured as a domain master.\n"));
  5354. +      }
  5355.    
  5356. -  if (lp_domain_master())
  5357. +      break;
  5358. +    }
  5359. +
  5360. +    case MST_DOMAIN_TST: /* while we were still a master browser... */
  5361.      {
  5362. -      DEBUG(4,("Domain master: adding names...\n"));
  5363. -      
  5364. -      /* add domain master and domain member names or register with WINS */
  5365. -      add_name_entry(work->work_group,0x1b,NB_ACTIVE);
  5366. -      work->ServerType |= SV_TYPE_DOMAIN_MASTER;
  5367. +      /* update our server status */
  5368. +      if (lp_domain_master())
  5369. +      {
  5370. +        struct subnet_record *d1;
  5371. +        uint32 update_type = 0;
  5372. +
  5373. +        DEBUG(3,("domain third stage: samba is now a domain master.\n"));
  5374. +        work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
  5375. +
  5376. +        update_type |= SV_TYPE_DOMAIN_MASTER;
  5377.        
  5378. -      if (lp_domain_logons())
  5379. -    {
  5380. -      work->ServerType |= SV_TYPE_DOMAIN_CTRL;
  5381. -      work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
  5382. -    }
  5383. -    }
  5384. -  
  5385. -  /* update our server status */
  5386. -  add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
  5387. -  add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
  5388. +        if (lp_domain_logons())
  5389. +        {
  5390. +          update_type |= SV_TYPE_DOMAIN_CTRL;
  5391. +        }
  5392. +
  5393. +        work->ServerType |= update_type;
  5394. +        add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
  5395. +
  5396. +        for (d1 = subnetlist; d1; d1 = d1->next)
  5397. +        {
  5398. +            struct work_record *w;
  5399. +            if (ip_equal(d1->bcast_ip, d->bcast_ip)) continue;
  5400. +
  5401. +            for (w = d1->workgrouplist; w; w = w->next)
  5402. +            {
  5403. +                struct server_record *s = find_server(w, myname);
  5404. +                if (strequal(w->work_group, work->work_group))
  5405. +                {
  5406. +                    w->ServerType |= update_type;
  5407. +                }
  5408. +                if (s)
  5409. +                {
  5410. +                    s->serv.type |= update_type;
  5411. +                    DEBUG(4,("found server %s on %s: update to %8x\n",
  5412. +                                    s->serv.name, inet_ntoa(d1->bcast_ip),
  5413. +                                    s->serv.type));
  5414. +                }
  5415. +            }
  5416. +        }
  5417. +      }
  5418.    
  5419. -  if (d->my_interface)
  5420. +      break;
  5421. +    }
  5422. +
  5423. +    case MST_DOMAIN:
  5424.      {
  5425. -      /* ask all servers on our local net to announce to us */
  5426. -      announce_request(work, d->bcast_ip);
  5427. +      /* don't have to do anything: just report success */
  5428. +      DEBUG(3,("fifth stage: there isn't one yet!\n"));
  5429. +      break;
  5430.      }
  5431. +  }
  5432.  }
  5433.  
  5434.  
  5435.  /*******************************************************************
  5436. -  unbecome the master browser
  5437. +  unbecome the master browser. initates removal of necessary netbios 
  5438. +  names, and tells the world that we are no longer a master browser.
  5439.    ******************************************************************/
  5440. -void become_nonmaster(struct subnet_record *d, struct work_record *work)
  5441. +void become_nonmaster(struct subnet_record *d, struct work_record *work,
  5442. +                int remove_type)
  5443.  {
  5444. +  int new_server_type = work->ServerType;
  5445. +
  5446.    DEBUG(2,("Becoming non-master for %s\n",work->work_group));
  5447.    
  5448. -  work->ServerType &= ~SV_TYPE_MASTER_BROWSER;
  5449. -  work->ServerType &= ~SV_TYPE_DOMAIN_MASTER;
  5450. -  work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
  5451. -  
  5452. -  work->ElectionCriterion &= ~0x4;
  5453. -  
  5454. -  remove_name_entry(work->work_group,0x1b);
  5455. -  remove_name_entry(work->work_group,0x1d);
  5456. -  remove_name_entry(MSBROWSE        ,0x01);
  5457. +  /* can only remove master or domain types with this function */
  5458. +  remove_type &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
  5459. +
  5460. +  /* unbecome a master browser; unbecome a domain master, too :-( */
  5461. +  if (remove_type & SV_TYPE_MASTER_BROWSER)
  5462. +    remove_type |= SV_TYPE_DOMAIN_MASTER;
  5463. +
  5464. +  new_server_type &= ~remove_type;
  5465. +
  5466. +  if (!(new_server_type & (SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER)))
  5467. +  {
  5468. +    /* no longer a master browser of any sort */
  5469. +
  5470. +      work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
  5471. +    work->ElectionCriterion &= ~0x4;
  5472. +    work->state = MST_NONE;
  5473. +
  5474. +    /* announce ourselves as no longer active as a master browser. */
  5475. +    announce_server(d, work, work->work_group, myname, 0, 0);
  5476. +    remove_name_entry(d,MSBROWSE        ,0x01);
  5477. +  }
  5478. +  
  5479. +  work->ServerType = new_server_type;
  5480. +
  5481. +  if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
  5482. +  {
  5483. +    if (work->state == MST_DOMAIN)
  5484. +      work->state = MST_BROWSER;
  5485. +    remove_name_entry(d,work->work_group,0x1b);
  5486. +    
  5487. +  }
  5488. +
  5489. +  if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
  5490. +  {
  5491. +    if (work->state >= MST_BROWSER)
  5492. +      work->state = MST_NONE;
  5493. +    remove_name_entry(d,work->work_group,0x1d);
  5494. +  }
  5495.  }
  5496.  
  5497.  
  5498. @@ -234,27 +489,29 @@
  5499.    lastime = t;
  5500.    
  5501.    for (d = subnetlist; d; d = d->next)
  5502. -    {
  5503. -      struct work_record *work;
  5504. -      for (work = d->workgrouplist; work; work = work->next)
  5505. +  {
  5506. +    struct work_record *work;
  5507. +    for (work = d->workgrouplist; work; work = work->next)
  5508.      {
  5509.        if (work->RunningElection)
  5510. -        {
  5511. -          send_election(d,work->work_group, work->ElectionCriterion,
  5512. +      {
  5513. +        send_election(d,work->work_group, work->ElectionCriterion,
  5514.                  t-StartupTime,myname);
  5515.            
  5516. -          if (work->ElectionCount++ >= 4)
  5517. +        if (work->ElectionCount++ >= 4)
  5518.          {
  5519.            /* I won! now what :-) */
  5520.            DEBUG(2,(">>> Won election on %s %s <<<\n",
  5521.                 work->work_group,inet_ntoa(d->bcast_ip)));
  5522.            
  5523.            work->RunningElection = False;
  5524. +          work->state = MST_NONE;
  5525. +
  5526.            become_master(d, work);
  5527.          }
  5528. -        }
  5529. +      }
  5530.      }
  5531. -    }
  5532. +  }
  5533.  }
  5534.  
  5535.  
  5536. @@ -292,7 +549,7 @@
  5537.  {
  5538.    struct dgram_packet *dgram = &p->packet.dgram;
  5539.    struct in_addr ip = dgram->header.source_ip;
  5540. -  struct subnet_record *d = find_domain(ip);
  5541. +  struct subnet_record *d = find_subnet(ip);
  5542.    int version = CVAL(buf,0);
  5543.    uint32 criterion = IVAL(buf,1);
  5544.    int timeup = IVAL(buf,5)/1000;
  5545. @@ -320,6 +577,7 @@
  5546.          {
  5547.            work->needelection = True;
  5548.            work->ElectionCount=0;
  5549. +          work->state = MST_NONE;
  5550.          }
  5551.          }
  5552.        else
  5553. @@ -334,9 +592,10 @@
  5554.            
  5555.            /* if we are the master then remove our masterly names */
  5556.            if (AM_MASTER(work))
  5557. -            {
  5558. -              become_nonmaster(d, work);
  5559. -            }
  5560. +          {
  5561. +              become_nonmaster(d, work,
  5562. +                    SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
  5563. +          }
  5564.          }
  5565.          }
  5566.      }
  5567. @@ -346,6 +605,11 @@
  5568.  
  5569.  /****************************************************************************
  5570.    checks whether a browser election is to be run on any workgroup
  5571. +
  5572. +  this function really ought to return the time between election
  5573. +  packets (which depends on whether samba intends to be a domain
  5574. +  master or a master browser) in milliseconds.
  5575. +
  5576.    ***************************************************************************/
  5577.  BOOL check_elections(void)
  5578.  {
  5579. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameelect.doc samba-1.9.16alpha11/source/nameelect.doc
  5580. --- samba-1.9.16alpha10/source/nameelect.doc    Thu Jan  1 10:00:00 1970
  5581. +++ samba-1.9.16alpha11/source/nameelect.doc    Thu Jul 11 04:48:26 1996
  5582. @@ -0,0 +1,214 @@
  5583. +
  5584. +the module nameelect.c deals with initiating, winning, losing
  5585. +browsing elections, and checking if browsers are still around,
  5586. +and the consequences of getting involved in all this.
  5587. +
  5588. +an election packet can be received at any time, which will initiate
  5589. +an election.  samba can also detect that there is no longer a
  5590. +master browser and will initiate an election.
  5591. +
  5592. +there is one way to become a master browser, but there are two
  5593. +ways to un-become a master browser.  if you lose an election, you
  5594. +must stop being a master browser. if you fail to register your
  5595. +unique special browser names (either on your local subnet or with
  5596. +the WINS server) then you must stop being a master browser.
  5597. +
  5598. +this is a double fail-safe mechanism to ensure that there is only
  5599. +one master browser per workgroup per subnet (and one primary domain
  5600. +controller - domain master browser - per domain (workgroup) per
  5601. +wide area network).
  5602. +
  5603. +(a wide area network is created when one or more servers on a
  5604. +broadcast-isolated subnet point to the same WINS server).
  5605. +
  5606. +
  5607. +/*************************************************************************
  5608. +  check_elections()
  5609. +  *************************************************************************/
  5610. +
  5611. +this function returns True if samba is in the process of running an
  5612. +election on any of its interfaces. a better version of this function
  5613. +should return the time-out period in between election packets, in
  5614. +milliseconds.
  5615. +
  5616. +
  5617. +/*************************************************************************
  5618. +  process_election()
  5619. +  *************************************************************************/
  5620. +
  5621. +this function is responsible for dealing with the receipt of an election
  5622. +browse MAILSLOT packet.
  5623. +
  5624. +if samba is running an election, it checks the criteria in the packet
  5625. +received using win_election() to see if it has lost the election or if
  5626. +it should join in the election.
  5627. +
  5628. +if it loses the election, then it becomes a non-master.
  5629. +
  5630. +
  5631. +/*************************************************************************
  5632. +  win_election()
  5633. +  *************************************************************************/
  5634. +
  5635. +this function returns True if samba has won an election. the criteria
  5636. +in order of precedence are:
  5637. +
  5638. +the election version; the election criteria; the time since samba was
  5639. +started; and as a last resort, a name comparison is used.
  5640. +
  5641. +
  5642. +/*************************************************************************
  5643. +  run_elections()
  5644. +  *************************************************************************/
  5645. +
  5646. +this function is responsible for sending out election packets if
  5647. +samba is running in an election. once the fourth packet is sent
  5648. +out, it is assumed that we have won, and samba initiates becoming
  5649. +a master browser.
  5650. +
  5651. +(it looks like samba sends out an extra packet just to be sure...)
  5652. +
  5653. +
  5654. +/*************************************************************************
  5655. +  become_nonmaster()
  5656. +  *************************************************************************/
  5657. +
  5658. +this function is responsible for down-grading samba's status from
  5659. +either domain master to master browser or nothing, or master browser
  5660. +to nothing, depending on its current status.
  5661. +
  5662. +samba can become a non-master in three ways: by losing an election -
  5663. +see process_election(); by having one of its special browser names
  5664. +de-registered - see name_unregister_work(); by receiving and
  5665. +processing a browser reset packet - see process_reset_browser().
  5666. +
  5667. +when samba stops being a domain master, it must release its unique
  5668. +0x1b name. when samba stops being a master browser, it must release
  5669. +its unique 0x1d name.
  5670. +
  5671. +becoming non-master is done on a per-subnet basis.
  5672. +
  5673. +
  5674. +/*************************************************************************
  5675. +  become_master()
  5676. +  *************************************************************************/
  5677. +
  5678. +this function is responsible for slowly turning samba into a
  5679. +master browser or a domain master (primary domain controller).
  5680. +
  5681. +
  5682. +this is done in stages. note that this could take a while, 
  5683. +particularly on a broadcast subnet, as we have to wait for
  5684. +the implicit registration of each name to be accepted.
  5685. +
  5686. +as each name is successfully registered, become_master() is
  5687. +called again via name_register_work(), in order to initiate
  5688. +the next stage (see dead_netbios_entry() - deals with implicit
  5689. +name registration and response_name_reg() - deals with explicit
  5690. +registration with a WINS server).
  5691. +
  5692. +stage 1: was MST_NONE - go to MST_NONE and register ^1^2__MSBROWSE__^2^1.
  5693. +stage 2: was MST_WON  - go to MST_MSB  and register WORKGROUP(0x1d)
  5694. +stage 3: was MST_MSB  - go to MST_BROWSER and register WORKGROUP(0x1b)
  5695. +stage 4: was MST_BROWSER - go to MST_DOMAIN (do not pass GO, do not...)
  5696. +
  5697. +note that this code still does not cope with the distinction
  5698. +between different types of nodes, particularly between M and P
  5699. +nodes (see rfc1001.txt). that will be developed later.
  5700. +
  5701. +
  5702. +/*************************************************************************
  5703. +  name_register_work()
  5704. +  *************************************************************************/
  5705. +
  5706. +this function is called when a NetBIOS name is successfully
  5707. +registered. it will add the registered name into samba's NetBIOS
  5708. +records.
  5709. +
  5710. +it has the additional responsibility that when samba is becoming
  5711. +a master browser, it must initiate the next stage in the progress
  5712. +towards becoming a master browser.
  5713. +
  5714. +implicit name registration is done through dead_netbios_entry()
  5715. +by time-out. explicit name registration is done through
  5716. +response_name_reg() with a WINS server.
  5717. +
  5718. +
  5719. +/*************************************************************************
  5720. +  name_unregister_work()
  5721. +  *************************************************************************/
  5722. +
  5723. +this function is called when there is an objection to a NetBIOS
  5724. +name being registered. this will always be done through a negative
  5725. +response to a name registration, whether it be by a host that
  5726. +already owns the unique name being registered on a subnet, or
  5727. +by a WINS server.
  5728. +
  5729. +the name being objected to must be removed from samba's records.
  5730. +
  5731. +it has the additional responsibility of checking whether samba is
  5732. +currently a master browser or not, and if so it should initiate
  5733. +becoming a non-master.
  5734. +
  5735. +
  5736. +
  5737. +/*************************************************************************
  5738. +  send_election()
  5739. +  *************************************************************************/
  5740. +
  5741. +this function is responsible for sending a browse mailslot 
  5742. +datagram election packet (of type ANN_Election). it constructs
  5743. +the packet with all the relevant info needed to participate:
  5744. +election version; election criteria; time since startup and
  5745. +our name.
  5746. +
  5747. +this function can be used to ensure that initiate but lose an
  5748. +election by specifying a criteria and time up of zero. this
  5749. +is necessary if we are a master browser and we are about to
  5750. +go down (politely!) - see nmbd.c:sig_term().
  5751. +
  5752. +
  5753. +/*************************************************************************
  5754. +  browser_gone()
  5755. +  *************************************************************************/
  5756. +
  5757. +this function is responsible for dealing with the instance when
  5758. +the master browser we thought was present on a subnet is no longer
  5759. +responding.
  5760. +
  5761. +if it is samba's workgroup, and it's a local interface, samba
  5762. +detects that it can participate in an election on that interface
  5763. +and potentially become a master browser or domain master.
  5764. +
  5765. +if it's a local subnet and not one of samba's workgroups, then
  5766. +samba will force an election (which it is not obliged to do).
  5767. +remove_workgroup() will be expected to remove all references
  5768. +to this workgroup and the servers in it from the database.
  5769. +
  5770. +if it's a remote subnet and not one of samba's workgroups then
  5771. +no election is forced, and remove_workgroup() will be expected
  5772. +to remove all server entries from this workgroup _except_ those
  5773. +added from the lmhosts file. if there are entries added from
  5774. +the lmhosts file, then the workgroup entry will remain,
  5775. +otherwise it too will be removed.
  5776. +
  5777. +
  5778. +/*************************************************************************
  5779. +  check_master_browser()
  5780. +  *************************************************************************/
  5781. +
  5782. +this function is responsible for periodically checking whether
  5783. +master browsers that samba expects to be alive are alive. this
  5784. +is done every CHECK_TIME_MST_BROWSE minutes.
  5785. +
  5786. +for every workgroup record for which samba is not a master browser,
  5787. +on both local and remote interfaces, samba will initiate a
  5788. +broadcast query for a master browser on that subnet.
  5789. +
  5790. +(browser_gone() will be called to deal with the case where no
  5791. +response is received to the NAME_QUERY_MST_CHK initiated here.
  5792. +no action is required when a response _is_ received, however:
  5793. +see nameservresp.c:response_process() and dead_netbios_entry()
  5794. +for details)
  5795. +
  5796. +
  5797. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namelogon.c samba-1.9.16alpha11/source/namelogon.c
  5798. --- samba-1.9.16alpha10/source/namelogon.c    Thu Jan  1 10:00:00 1970
  5799. +++ samba-1.9.16alpha11/source/namelogon.c    Wed Jul  3 01:31:12 1996
  5800. @@ -0,0 +1,119 @@
  5801. +/* 
  5802. +   Unix SMB/Netbios implementation.
  5803. +   Version 1.9.
  5804. +   NBT netbios routines and daemon - version 2
  5805. +   Copyright (C) Andrew Tridgell 1994-1995
  5806. +   
  5807. +   This program is free software; you can redistribute it and/or modify
  5808. +   it under the terms of the GNU General Public License as published by
  5809. +   the Free Software Foundation; either version 2 of the License, or
  5810. +   (at your option) any later version.
  5811. +   
  5812. +   This program is distributed in the hope that it will be useful,
  5813. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  5814. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  5815. +   GNU General Public License for more details.
  5816. +   
  5817. +   You should have received a copy of the GNU General Public License
  5818. +   along with this program; if not, write to the Free Software
  5819. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  5820. +   
  5821. +   Revision History:
  5822. +
  5823. +   14 jan 96: lkcl@pires.co.uk
  5824. +   added multiple workgroup domain master support
  5825. +
  5826. +*/
  5827. +
  5828. +#include "includes.h"
  5829. +
  5830. +extern int ClientDGRAM;
  5831. +
  5832. +#define TEST_CODE /* want to debug unknown browse packets */
  5833. +
  5834. +extern int DEBUGLEVEL;
  5835. +
  5836. +extern pstring myname;
  5837. +
  5838. +
  5839. +/****************************************************************************
  5840. +   process a domain logon packet
  5841. +   **************************************************************************/
  5842. +void process_logon_packet(struct packet_struct *p,char *buf,int len)
  5843. +{
  5844. +  struct dgram_packet *dgram = &p->packet.dgram;
  5845. +  struct in_addr ip = dgram->header.source_ip;
  5846. +  struct subnet_record *d = find_subnet(ip);
  5847. +  char *logname,*q;
  5848. +  char *reply_name;
  5849. +  BOOL add_slashes = False;
  5850. +  pstring outbuf;
  5851. +  int code,reply_code;
  5852. +  struct work_record *work;
  5853. +  
  5854. +  if (!d) return;
  5855. +  
  5856. +  if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False))) 
  5857. +    return;
  5858. +  
  5859. +  if (!lp_domain_logons()) {
  5860. +    DEBUG(3,("No domain logons\n"));
  5861. +    return;
  5862. +  }
  5863. +  if (!listening_name(work, &dgram->dest_name))
  5864. +    {
  5865. +      DEBUG(4,("Not listening to that domain\n"));
  5866. +      return;
  5867. +    }
  5868. +  
  5869. +  code = SVAL(buf,0);
  5870. +  switch (code) {
  5871. +  case 0:    
  5872. +    {
  5873. +      char *machine = buf+2;
  5874. +      char *user = skip_string(machine,1);
  5875. +      logname = skip_string(user,1);
  5876. +      reply_code = 6;
  5877. +      reply_name = myname;
  5878. +      add_slashes = True;
  5879. +      DEBUG(3,("Domain login request from %s(%s) user=%s\n",
  5880. +            machine,inet_ntoa(p->ip),user));
  5881. +    }
  5882. +    break;
  5883. +  case 7:    
  5884. +    {
  5885. +      char *machine = buf+2;
  5886. +      logname = skip_string(machine,1);
  5887. +      reply_code = 7;
  5888. +      reply_name = lp_domain_controller();
  5889. +      if (!*reply_name) {
  5890. +     DEBUG(3,("No domain controller configured\n"));
  5891. +     return;
  5892. +      }
  5893. +      DEBUG(3,("GETDC request from %s(%s)\n",
  5894. +            machine,inet_ntoa(p->ip)));
  5895. +    }
  5896. +    break;
  5897. +  default:
  5898. +    DEBUG(3,("Unknown domain request %d\n",code));
  5899. +    return;
  5900. +  }
  5901. +  
  5902. +  bzero(outbuf,sizeof(outbuf));
  5903. +  q = outbuf;
  5904. +  SSVAL(q,0,reply_code);
  5905. +  q += 2;
  5906. +  if (add_slashes) {
  5907. +    strcpy(q,"\\\\");
  5908. +    q += 2;
  5909. +  }
  5910. +  StrnCpy(q,reply_name,16);
  5911. +  strupper(q);
  5912. +  q = skip_string(q,1);
  5913. +  SSVAL(q,0,0xFFFF);
  5914. +  q += 2;
  5915. +  
  5916. +  send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
  5917. +               myname,&dgram->source_name.name[0],0x20,0,p->ip,
  5918. +              *iface_ip(p->ip));  
  5919. +}
  5920. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namelogon.doc samba-1.9.16alpha11/source/namelogon.doc
  5921. --- samba-1.9.16alpha10/source/namelogon.doc    Thu Jan  1 10:00:00 1970
  5922. +++ samba-1.9.16alpha11/source/namelogon.doc    Sun Jul  7 22:35:55 1996
  5923. @@ -0,0 +1,9 @@
  5924. +this module deals with the first stage of domain logons. there is much
  5925. +more work to be done on this: it's all totally undocumented.
  5926. +
  5927. +
  5928. +/*************************************************************************
  5929. +  process_logon_packet()
  5930. +  *************************************************************************/
  5931. +
  5932. +a function that processes logon packets (the most helpful comment yet :-).
  5933. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namepacket.c samba-1.9.16alpha11/source/namepacket.c
  5934. --- samba-1.9.16alpha10/source/namepacket.c    Thu Jan  1 10:00:00 1970
  5935. +++ samba-1.9.16alpha11/source/namepacket.c    Thu Jul 18 20:53:15 1996
  5936. @@ -0,0 +1,581 @@
  5937. +/* 
  5938. +   Unix SMB/Netbios implementation.
  5939. +   Version 1.9.
  5940. +   NBT netbios routines and daemon - version 2
  5941. +   Copyright (C) Andrew Tridgell 1994-1995
  5942. +   
  5943. +   This program is free software; you can redistribute it and/or modify
  5944. +   it under the terms of the GNU General Public License as published by
  5945. +   the Free Software Foundation; either version 2 of the License, or
  5946. +   (at your option) any later version.
  5947. +   
  5948. +   This program is distributed in the hope that it will be useful,
  5949. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  5950. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  5951. +   GNU General Public License for more details.
  5952. +   
  5953. +   You should have received a copy of the GNU General Public License
  5954. +   along with this program; if not, write to the Free Software
  5955. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  5956. +   
  5957. +   Revision History:
  5958. +
  5959. +   14 jan 96: lkcl@pires.co.uk
  5960. +   added multiple workgroup domain master support
  5961. +
  5962. +*/
  5963. +
  5964. +#include "includes.h"
  5965. +
  5966. +extern int ClientNMB;
  5967. +extern int ClientDGRAM;
  5968. +
  5969. +extern int DEBUGLEVEL;
  5970. +
  5971. +extern int num_response_packets;
  5972. +
  5973. +BOOL CanRecurse = True;
  5974. +extern pstring scope;
  5975. +extern struct in_addr ipgrp;
  5976. +
  5977. +static uint16 name_trn_id=0;
  5978. +
  5979. +
  5980. +/***************************************************************************
  5981. +  updates the unique transaction identifier
  5982. +  **************************************************************************/
  5983. +void debug_browse_data(char *outbuf, int len)
  5984. +{
  5985. +    int i,j;
  5986. +    for (i = 0; i < len; i+= 16)
  5987. +      {
  5988. +    DEBUG(4, ("%3x char ", i));
  5989. +    
  5990. +    for (j = 0; j < 16; j++)
  5991. +      {
  5992. +        unsigned char x = outbuf[i+j];
  5993. +        if (x < 32 || x > 127) x = '.';
  5994. +        
  5995. +        if (i+j >= len) break;
  5996. +        DEBUG(4, ("%c", x));
  5997. +      }
  5998. +    
  5999. +    DEBUG(4, (" hex ", i));
  6000. +    
  6001. +    for (j = 0; j < 16; j++)
  6002. +      {
  6003. +        if (i+j >= len) break;
  6004. +        DEBUG(4, (" %02x", outbuf[i+j]));
  6005. +      }
  6006. +    
  6007. +    DEBUG(4, ("\n"));
  6008. +      }
  6009. +    
  6010. +}
  6011. +
  6012. +
  6013. +/***************************************************************************
  6014. +  updates the unique transaction identifier
  6015. +  **************************************************************************/
  6016. +static void update_name_trn_id(void)
  6017. +{
  6018. +  if (!name_trn_id)
  6019. +  {
  6020. +    name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
  6021. +  }
  6022. +  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
  6023. +}
  6024. +
  6025. +
  6026. +/****************************************************************************
  6027. +  initiate a netbios packet
  6028. +  ****************************************************************************/
  6029. +void initiate_netbios_packet(uint16 *id,
  6030. +                int fd,int quest_type,char *name,int name_type,
  6031. +                int nb_flags,BOOL bcast,BOOL recurse,
  6032. +                struct in_addr to_ip)
  6033. +{
  6034. +  struct packet_struct p;
  6035. +  struct nmb_packet *nmb = &p.packet.nmb;
  6036. +  struct res_rec additional_rec;
  6037. +  char *packet_type = "unknown";
  6038. +  int opcode = -1;
  6039. +
  6040. +  if (!id) return;
  6041. +
  6042. +  if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
  6043. +  if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
  6044. +  if (quest_type == NMB_REG   ) { packet_type = "nmb_reg"; opcode = 5; }
  6045. +  if (quest_type == NMB_REL   ) { packet_type = "nmb_rel"; opcode = 6; }
  6046. +  
  6047. +  DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
  6048. +       packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
  6049. +
  6050. +  if (opcode == -1) return;
  6051. +
  6052. +  bzero((char *)&p,sizeof(p));
  6053. +
  6054. +  if (*id == 0xffff) {
  6055. +    update_name_trn_id();
  6056. +    *id = name_trn_id; /* allow resending with same id */
  6057. +  }
  6058. +
  6059. +  nmb->header.name_trn_id = *id;
  6060. +  nmb->header.opcode = opcode;
  6061. +  nmb->header.response = False;
  6062. +
  6063. +  nmb->header.nm_flags.bcast = bcast;
  6064. +  nmb->header.nm_flags.recursion_available = CanRecurse;
  6065. +  nmb->header.nm_flags.recursion_desired = recurse;
  6066. +  nmb->header.nm_flags.trunc = False;
  6067. +  nmb->header.nm_flags.authoritative = False;
  6068. +
  6069. +  nmb->header.rcode = 0;
  6070. +  nmb->header.qdcount = 1;
  6071. +  nmb->header.ancount = 0;
  6072. +  nmb->header.nscount = 0;
  6073. +  nmb->header.arcount = (quest_type==NMB_REG || quest_type==NMB_REL) ? 1 : 0;
  6074. +  
  6075. +  make_nmb_name(&nmb->question.question_name,name,name_type,scope);
  6076. +  
  6077. +  nmb->question.question_type = quest_type;
  6078. +  nmb->question.question_class = 0x1;
  6079. +  
  6080. +  if (quest_type == NMB_REG || quest_type == NMB_REL)
  6081. +    {
  6082. +      nmb->additional = &additional_rec;
  6083. +      bzero((char *)nmb->additional,sizeof(*nmb->additional));
  6084. +      
  6085. +      nmb->additional->rr_name  = nmb->question.question_name;
  6086. +      nmb->additional->rr_type  = nmb->question.question_type;
  6087. +      nmb->additional->rr_class = nmb->question.question_class;
  6088. +      
  6089. +      nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0;
  6090. +      nmb->additional->rdlength = 6;
  6091. +      nmb->additional->rdata[0] = nb_flags;
  6092. +      putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
  6093. +    }
  6094. +  
  6095. +  p.ip = to_ip;
  6096. +  p.port = NMB_PORT;
  6097. +  p.fd = fd;
  6098. +  p.timestamp = time(NULL);
  6099. +  p.packet_type = NMB_PACKET;
  6100. +  
  6101. +  if (!send_packet(&p)) *id = 0xffff;
  6102. +  
  6103. +  return;
  6104. +}
  6105. +
  6106. +
  6107. +/****************************************************************************
  6108. +  reply to a netbios name packet 
  6109. +  ****************************************************************************/
  6110. +void reply_netbios_packet(struct packet_struct *p1,int trn_id,
  6111. +                int rcode, int rcv_code, int opcode, BOOL recurse,
  6112. +                struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
  6113. +                char *data,int len)
  6114. +{
  6115. +  struct packet_struct p;
  6116. +  struct nmb_packet *nmb = &p.packet.nmb;
  6117. +  struct res_rec answers;
  6118. +  char *packet_type = "unknown";
  6119. +  BOOL recursion_desired = False;
  6120. +  
  6121. +  p = *p1;
  6122. +
  6123. +  switch (rcv_code)
  6124. +  {
  6125. +    case NMB_STATUS:
  6126. +    {
  6127. +      packet_type = "nmb_status";
  6128. +      recursion_desired = True;
  6129. +      break;
  6130. +    }
  6131. +    case NMB_QUERY:
  6132. +    {
  6133. +      packet_type = "nmb_query";
  6134. +      recursion_desired = True;
  6135. +      break;
  6136. +    }
  6137. +    case NMB_REG:
  6138. +    {
  6139. +      packet_type = "nmb_reg";
  6140. +      recursion_desired = True;
  6141. +      break;
  6142. +    }
  6143. +    case NMB_REL:
  6144. +    {
  6145. +      packet_type = "nmb_rel";
  6146. +      recursion_desired = False;
  6147. +      break;
  6148. +    }
  6149. +    case NMB_WAIT_ACK:
  6150. +    {
  6151. +      packet_type = "nmb_wack";
  6152. +      recursion_desired = False;
  6153. +      break;
  6154. +    }
  6155. +    default:
  6156. +    {
  6157. +      DEBUG(1,("replying netbios packet: %s %s\n",
  6158. +                packet_type, namestr(rr_name), inet_ntoa(p.ip)));
  6159. +
  6160. +      return;
  6161. +    }
  6162. +  }
  6163. +
  6164. +  DEBUG(4,("replying netbios packet: %s %s\n",
  6165. +       packet_type, namestr(rr_name), inet_ntoa(p.ip)));
  6166. +
  6167. +  nmb->header.name_trn_id = trn_id;
  6168. +  nmb->header.opcode = opcode;
  6169. +  nmb->header.response = True;
  6170. +  nmb->header.nm_flags.bcast = False;
  6171. +  nmb->header.nm_flags.recursion_available = recurse;
  6172. +  nmb->header.nm_flags.recursion_desired = recursion_desired;
  6173. +  nmb->header.nm_flags.trunc = False;
  6174. +  nmb->header.nm_flags.authoritative = True;
  6175. +  
  6176. +  nmb->header.qdcount = 0;
  6177. +  nmb->header.ancount = 1;
  6178. +  nmb->header.nscount = 0;
  6179. +  nmb->header.arcount = 0;
  6180. +  nmb->header.rcode = 0;
  6181. +  
  6182. +  bzero((char*)&nmb->question,sizeof(nmb->question));
  6183. +  
  6184. +  nmb->answers = &answers;
  6185. +  bzero((char*)nmb->answers,sizeof(*nmb->answers));
  6186. +  
  6187. +  nmb->answers->rr_name  = *rr_name;
  6188. +  nmb->answers->rr_type  = rr_type;
  6189. +  nmb->answers->rr_class = rr_class;
  6190. +  nmb->answers->ttl      = ttl;
  6191. +  
  6192. +  if (data && len)
  6193. +    {
  6194. +      nmb->answers->rdlength = len;
  6195. +      memcpy(nmb->answers->rdata, data, len);
  6196. +    }
  6197. +  
  6198. +  p.packet_type = NMB_PACKET;
  6199. +  
  6200. +  debug_nmb_packet(&p);
  6201. +  
  6202. +  send_packet(&p);
  6203. +}
  6204. +
  6205. +
  6206. +/*******************************************************************
  6207. +  the global packet linked-list. incoming entries are added to the
  6208. +  end of this list.  it is supposed to remain fairly short so we
  6209. +  won't bother with an end pointer.
  6210. +  ******************************************************************/
  6211. +static struct packet_struct *packet_queue = NULL;
  6212. +
  6213. +/*******************************************************************
  6214. +  queue a packet into the packet queue
  6215. +  ******************************************************************/
  6216. +void queue_packet(struct packet_struct *packet)
  6217. +{
  6218. +  struct packet_struct *p;
  6219. +
  6220. +  if (!packet_queue) {
  6221. +    packet->prev = NULL;
  6222. +    packet->next = NULL;
  6223. +    packet_queue = packet;
  6224. +    return;
  6225. +  }
  6226. +  
  6227. +  /* find the bottom */
  6228. +  for (p=packet_queue;p->next;p=p->next) ;
  6229. +
  6230. +  p->next = packet;
  6231. +  packet->next = NULL;
  6232. +  packet->prev = p;
  6233. +}
  6234. +
  6235. +
  6236. +/****************************************************************************
  6237. +  process udp 138 datagrams
  6238. +  ****************************************************************************/
  6239. +static void process_dgram(struct packet_struct *p)
  6240. +{
  6241. +  char *buf;
  6242. +  char *buf2;
  6243. +  int len;
  6244. +  struct dgram_packet *dgram = &p->packet.dgram;
  6245. +
  6246. +  if (dgram->header.msg_type != 0x10 &&
  6247. +      dgram->header.msg_type != 0x11 &&
  6248. +      dgram->header.msg_type != 0x12) {
  6249. +    /* don't process error packets etc yet */
  6250. +    return;
  6251. +  }
  6252. +
  6253. +  buf = &dgram->data[0];
  6254. +  buf -= 4; /* XXXX for the pseudo tcp length - 
  6255. +           someday I need to get rid of this */
  6256. +
  6257. +  if (CVAL(buf,smb_com) != SMBtrans) return;
  6258. +
  6259. +  len = SVAL(buf,smb_vwv11);
  6260. +  buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
  6261. +
  6262. +  DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
  6263. +       namestr(&dgram->source_name),namestr(&dgram->dest_name),
  6264. +       smb_buf(buf),CVAL(buf2,0),len));
  6265. +
  6266. +  if (len <= 0) return;
  6267. +
  6268. +   /* datagram packet received for the browser mailslot */
  6269. +   if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
  6270. +     process_browse_packet(p,buf2,len);
  6271. +     return;
  6272. +   }
  6273. +
  6274. +   /* datagram packet received for the domain log on mailslot */
  6275. +   if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
  6276. +     process_logon_packet(p,buf2,len);
  6277. +     return;
  6278. +   }
  6279. +}
  6280. +
  6281. +/****************************************************************************
  6282. +  process a nmb packet
  6283. +  ****************************************************************************/
  6284. +static void process_nmb(struct packet_struct *p)
  6285. +{
  6286. +  struct nmb_packet *nmb = &p->packet.nmb;
  6287. +
  6288. +  debug_nmb_packet(p);
  6289. +
  6290. +  switch (nmb->header.opcode) 
  6291. +  {
  6292. +    case 8: /* what is this?? */
  6293. +    case NMB_REG:
  6294. +    case NMB_REG_REFRESH:
  6295. +    {
  6296. +    if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
  6297. +    if (nmb->header.response)
  6298. +      response_netbios_packet(p); /* response to registration dealt with here */
  6299. +    else
  6300. +      reply_name_reg(p);
  6301. +    break;
  6302. +    }
  6303. +      
  6304. +    case 0:
  6305. +    {
  6306. +      if (nmb->header.response)
  6307. +      {
  6308. +        switch (nmb->question.question_type)
  6309. +          {
  6310. +          case 0x0:
  6311. +        {
  6312. +          response_netbios_packet(p);
  6313. +          break;
  6314. +        }
  6315. +          }
  6316. +        return;
  6317. +      }
  6318. +      else if (nmb->header.qdcount>0) 
  6319. +      {
  6320. +        switch (nmb->question.question_type)
  6321. +          {
  6322. +          case NMB_QUERY:
  6323. +        {
  6324. +          reply_name_query(p);
  6325. +          break;
  6326. +        }
  6327. +          case NMB_STATUS:
  6328. +        {
  6329. +          reply_name_status(p);
  6330. +          break;
  6331. +        }
  6332. +          }
  6333. +        return;
  6334. +      }
  6335. +    break;
  6336. +      }
  6337. +      
  6338. +    case NMB_REL:
  6339. +    {
  6340. +      if (nmb->header.qdcount==0 || nmb->header.arcount==0)
  6341. +      {
  6342. +        DEBUG(2,("netbios release packet rejected\n"));
  6343. +        break;
  6344. +      }
  6345. +    
  6346. +    if (nmb->header.response)
  6347. +      response_netbios_packet(p); /* response to reply dealt with in here */
  6348. +    else
  6349. +      reply_name_release(p);
  6350. +      break;
  6351. +    }
  6352. +  }
  6353. +}
  6354. +
  6355. +
  6356. +/*******************************************************************
  6357. +  run elements off the packet queue till its empty
  6358. +  ******************************************************************/
  6359. +void run_packet_queue()
  6360. +{
  6361. +  struct packet_struct *p;
  6362. +
  6363. +  while ((p=packet_queue))
  6364. +    {
  6365. +      switch (p->packet_type)
  6366. +    {
  6367. +    case NMB_PACKET:
  6368. +      process_nmb(p);
  6369. +      break;
  6370. +      
  6371. +    case DGRAM_PACKET:
  6372. +      process_dgram(p);
  6373. +      break;
  6374. +    }
  6375. +      
  6376. +      packet_queue = packet_queue->next;
  6377. +      if (packet_queue) packet_queue->prev = NULL;
  6378. +      free_packet(p);
  6379. +    }
  6380. +}
  6381. +
  6382. +/****************************************************************************
  6383. +  listens for NMB or DGRAM packets, and queues them
  6384. +  ***************************************************************************/
  6385. +void listen_for_packets(BOOL run_election)
  6386. +{
  6387. +  fd_set fds;
  6388. +  int selrtn;
  6389. +  struct timeval timeout;
  6390. +
  6391. +  FD_ZERO(&fds);
  6392. +  FD_SET(ClientNMB,&fds);
  6393. +  FD_SET(ClientDGRAM,&fds);
  6394. +
  6395. +  /* during elections and when expecting a netbios response packet we need
  6396. +     to send election packets at one second intervals.
  6397. +     XXXX actually, it needs to be the interval (in ms) between time now and the
  6398. +     time we are expecting the next netbios packet */
  6399. +
  6400. +  timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
  6401. +  timeout.tv_usec = 0;
  6402. +
  6403. +  selrtn = sys_select(&fds,&timeout);
  6404. +
  6405. +  if (FD_ISSET(ClientNMB,&fds))
  6406. +    {
  6407. +      struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
  6408. +      if (packet) {
  6409. +#if 1
  6410. +    if (ismyip(packet->ip) &&
  6411. +        (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
  6412. +      DEBUG(5,("discarding own packet from %s:%d\n",
  6413. +           inet_ntoa(packet->ip),packet->port));      
  6414. +      free_packet(packet);
  6415. +    } else 
  6416. +#endif
  6417. +      {
  6418. +        queue_packet(packet);
  6419. +      }
  6420. +      }
  6421. +    }
  6422. +
  6423. +  if (FD_ISSET(ClientDGRAM,&fds))
  6424. +    {
  6425. +      struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
  6426. +      if (packet) {
  6427. +#if 1
  6428. +    if (ismyip(packet->ip) &&
  6429. +          (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
  6430. +      DEBUG(5,("discarding own packet from %s:%d\n",
  6431. +           inet_ntoa(packet->ip),packet->port));      
  6432. +      free_packet(packet);
  6433. +    } else
  6434. +#endif 
  6435. +      {
  6436. +        queue_packet(packet);
  6437. +      }
  6438. +      }
  6439. +    }
  6440. +}
  6441. +
  6442. +
  6443. +
  6444. +/****************************************************************************
  6445. +  construct and send a netbios DGRAM
  6446. +
  6447. +  Note that this currently sends all answers to port 138. thats the
  6448. +  wrong things to do! I should send to the requestors port. XXX
  6449. +  **************************************************************************/
  6450. +BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
  6451. +             char *dstname,int src_type,int dest_type,
  6452. +             struct in_addr dest_ip,struct in_addr src_ip)
  6453. +{
  6454. +  struct packet_struct p;
  6455. +  struct dgram_packet *dgram = &p.packet.dgram;
  6456. +  struct in_addr wins_ip = ipgrp;
  6457. +  char *ptr,*p2;
  6458. +  char tmp[4];
  6459. +
  6460. +  /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
  6461. +  if (ip_equal(wins_ip, dest_ip)) return False;
  6462. +
  6463. +  bzero((char *)&p,sizeof(p));
  6464. +
  6465. +  update_name_trn_id();
  6466. +
  6467. +  dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
  6468. +  dgram->header.flags.node_type = M_NODE;
  6469. +  dgram->header.flags.first = True;
  6470. +  dgram->header.flags.more = False;
  6471. +  dgram->header.dgm_id = name_trn_id;
  6472. +  dgram->header.source_ip = src_ip;
  6473. +  dgram->header.source_port = DGRAM_PORT;
  6474. +  dgram->header.dgm_length = 0; /* let build_dgram() handle this */
  6475. +  dgram->header.packet_offset = 0;
  6476. +  
  6477. +  make_nmb_name(&dgram->source_name,srcname,src_type,scope);
  6478. +  make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
  6479. +
  6480. +  ptr = &dgram->data[0];
  6481. +
  6482. +  /* now setup the smb part */
  6483. +  ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
  6484. +  memcpy(tmp,ptr,4);
  6485. +  set_message(ptr,17,17 + len,True);
  6486. +  memcpy(ptr,tmp,4);
  6487. +
  6488. +  CVAL(ptr,smb_com) = SMBtrans;
  6489. +  SSVAL(ptr,smb_vwv1,len);
  6490. +  SSVAL(ptr,smb_vwv11,len);
  6491. +  SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
  6492. +  SSVAL(ptr,smb_vwv13,3);
  6493. +  SSVAL(ptr,smb_vwv14,1);
  6494. +  SSVAL(ptr,smb_vwv15,1);
  6495. +  SSVAL(ptr,smb_vwv16,2);
  6496. +  p2 = smb_buf(ptr);
  6497. +  strcpy(p2,mailslot);
  6498. +  p2 = skip_string(p2,1);
  6499. +
  6500. +  memcpy(p2,buf,len);
  6501. +  p2 += len;
  6502. +
  6503. +  dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
  6504. +
  6505. +  p.ip = dest_ip;
  6506. +  p.port = DGRAM_PORT;
  6507. +  p.fd = ClientDGRAM;
  6508. +  p.timestamp = time(NULL);
  6509. +  p.packet_type = DGRAM_PACKET;
  6510. +
  6511. +  DEBUG(4,("send mailslot %s from %s %s", mailslot,
  6512. +                    inet_ntoa(src_ip),namestr(&dgram->source_name)));
  6513. +  DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
  6514. +
  6515. +  return(send_packet(&p));
  6516. +}
  6517. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namepacket.doc samba-1.9.16alpha11/source/namepacket.doc
  6518. --- samba-1.9.16alpha10/source/namepacket.doc    Thu Jan  1 10:00:00 1970
  6519. +++ samba-1.9.16alpha11/source/namepacket.doc    Sun Jul  7 22:35:55 1996
  6520. @@ -0,0 +1,106 @@
  6521. +this module deals with packets: sending, receiving, queueing
  6522. +and some basic interpretation (e.g it excludes datagram
  6523. +error packets at the moment).
  6524. +
  6525. +the packet queueing mechanism was originally introduced when
  6526. +samba dealt with responses by sending a packet, receiving
  6527. +packets and queueing all packets that didn't match up with
  6528. +the response expected. this is fine in a single-thread
  6529. +environment, but samba now deals with response packets by
  6530. +queueing the responses. to some extent, therefore, this
  6531. +queue_packet mechanism is redundant.
  6532. +
  6533. +
  6534. +/*************************************************************************
  6535. +  send_mailslot_reply()
  6536. +  *************************************************************************/
  6537. +
  6538. +this function is responsible for sending a MAILSLOT packet.
  6539. +
  6540. +it will _not_ send packets to the pseudo WINS subnet's address of 
  6541. +255.255.255.255: this would be disastrous.
  6542. +
  6543. +each packet sent out has a unique transaction identifier. this is done
  6544. +so that responses can be matched later with the original purpose for
  6545. +the packet being sent out in the first place.
  6546. +
  6547. +
  6548. +/*************************************************************************
  6549. +  listen_for_packets()
  6550. +  *************************************************************************/
  6551. +
  6552. +this function is responsible for reading NMB and DGRAM packets, and then
  6553. +queueing them. it will normally time-out for NMBD_SELECT_LOOP seconds, but
  6554. +if there is an election currently running or we are expecting a response
  6555. +then this time is reduced to 1 second.
  6556. +
  6557. +note: the time-out period needs refining to the millisecond level.
  6558. +
  6559. +
  6560. +/*************************************************************************
  6561. +  queue_packet()
  6562. +  *************************************************************************/
  6563. +
  6564. +this function is responsible for queueing any NMB and DGRAM packets passed
  6565. +to it. these packets will be removed from the queue in run_packet_queue().
  6566. +
  6567. +
  6568. +/*************************************************************************
  6569. +  run_packet_queue()
  6570. +  *************************************************************************/
  6571. +
  6572. +this function is responsible for taking a packet off the queue, 
  6573. +identifying whether it is an NMB or a DGRAM packet, processing
  6574. +it accordingly and deleting it. this process continues until
  6575. +there are no more packets on the queue.
  6576. +
  6577. +
  6578. +/*************************************************************************
  6579. +  process_nmb()
  6580. +  *************************************************************************/
  6581. +
  6582. +this function receives a packet identified as a netbios packet.
  6583. +it further identifies whether it is a response or a query packet.
  6584. +by identifying the type of packet (name registration, query etc)
  6585. +process_nmb() will call the appropriate function to deal with the
  6586. +type of packet received.
  6587. +
  6588. +
  6589. +/*************************************************************************
  6590. +  process_dgram()
  6591. +  *************************************************************************/
  6592. +
  6593. +this function is responsible for identifying whether the datagram
  6594. +packet received is a browser packet or a domain logon packet. it
  6595. +also does some filtering of certain types of packets (e.g it
  6596. +filters out error packets).
  6597. +
  6598. +
  6599. +/*************************************************************************
  6600. +  reply_netbios_packet()
  6601. +  *************************************************************************/
  6602. +
  6603. +this function is responsible for sending a reply to another NetBIOS
  6604. +packet from another host. it can be used to send a reply to a name
  6605. +registration, name release, name query or name status request.
  6606. +
  6607. +the reply can be either a positive or a negative one.
  6608. +
  6609. +
  6610. +/*************************************************************************
  6611. +  initiate_netbios_packet()
  6612. +  *************************************************************************/
  6613. +
  6614. +this function is responsible for construction a netbios packet and sending
  6615. +it. if the packet has not had a unique transaction id allocated to it,
  6616. +then initiate_netbios_packet() will give it one.
  6617. +
  6618. +
  6619. +/*************************************************************************
  6620. +  update_name_trn_id()
  6621. +  *************************************************************************/
  6622. +
  6623. +this function is responsible for allocating unique transaction identifiers
  6624. +for each new packet sent on the network.
  6625. +
  6626. +
  6627. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namequery.c samba-1.9.16alpha11/source/namequery.c
  6628. --- samba-1.9.16alpha10/source/namequery.c    Tue Jun  4 16:41:15 1996
  6629. +++ samba-1.9.16alpha11/source/namequery.c    Thu Jul 18 20:53:15 1996
  6630. @@ -173,6 +173,8 @@
  6631.          continue;
  6632.        }
  6633.  
  6634. +      debug_nmb_packet(p2);
  6635. +
  6636.        _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
  6637.        free_packet(p2);
  6638.        return(True);
  6639. @@ -266,6 +268,8 @@
  6640.          continue;
  6641.        }
  6642.        
  6643. +      debug_nmb_packet(p2);
  6644. +
  6645.        if (nmb2->header.opcode != 0 ||
  6646.            nmb2->header.nm_flags.bcast ||
  6647.            nmb2->header.rcode ||
  6648. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namequery.doc samba-1.9.16alpha11/source/namequery.doc
  6649. --- samba-1.9.16alpha10/source/namequery.doc    Thu Jan  1 10:00:00 1970
  6650. +++ samba-1.9.16alpha11/source/namequery.doc    Sun Jul  7 22:35:56 1996
  6651. @@ -0,0 +1,56 @@
  6652. +this module contains non-threaded versions of name status and name
  6653. +query functions. if a multi-threaded nmbd was to be written, these
  6654. +functions would be the starting point.
  6655. +
  6656. +at the moment, the expected response queueing system is used to
  6657. +replace these functions without needing to multi-thread nmbd.
  6658. +
  6659. +these functions are used in smbclient and nmblookup at present to
  6660. +avoid having the vast quantities of complex and unused code needed
  6661. +to support even a simple name query (or providing stubs for the
  6662. +unused side of these functions).
  6663. +
  6664. +there is a down-side to these functions, which is all microsoft's
  6665. +fault. microsoft machines always always reply to queries on the
  6666. +priveleged ports, rather than following the usual tcp/ip mechanism
  6667. +of replying on the client's port (the exception to this i am led
  6668. +to believe is windows nt 3.50).
  6669. +
  6670. +as a result of this, in order to receive a response to a name
  6671. +query from a microsoft machine, we must be able to listen on
  6672. +the priveleged netbios name server ports. this is simply not
  6673. +possible with some versions of unix, unless you have root access.
  6674. +
  6675. +it is also not possible if you run smbclient or nmblookup on an
  6676. +interface that already has been claimed by the netbios name server
  6677. +daemon nmbd.
  6678. +
  6679. +all in all, i wish that microsoft would fix this.
  6680. +
  6681. +a solution does exist: nmbd _does_ actually reply on the client's
  6682. +port, so if smbclient and nmblookup were to use nmbd as a proxy
  6683. +forwarder of queries (or to use samba's WINS capabilities) then
  6684. +a query could be made without needing access to the priveleged
  6685. +ports. in order to do this properly, samba must implement secured
  6686. +netbios name server functionality (see rfc1001.txt 15.1.6).
  6687. +
  6688. +
  6689. +/*************************************************************************
  6690. +  name_query()
  6691. +  *************************************************************************/
  6692. +
  6693. +
  6694. +
  6695. +/*************************************************************************
  6696. +  name_status()
  6697. +  *************************************************************************/
  6698. +
  6699. +
  6700. +
  6701. +/*************************************************************************
  6702. +  _interpret_node_status()
  6703. +  *************************************************************************/
  6704. +
  6705. +
  6706. +this is a older version of interpret_node_status().
  6707. +
  6708. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameresp.c samba-1.9.16alpha11/source/nameresp.c
  6709. --- samba-1.9.16alpha10/source/nameresp.c    Mon Jun 10 15:18:56 1996
  6710. +++ samba-1.9.16alpha11/source/nameresp.c    Thu Jul 18 20:53:15 1996
  6711. @@ -2,7 +2,7 @@
  6712.     Unix SMB/Netbios implementation.
  6713.     Version 1.9.
  6714.     NBT netbios library routines
  6715. -   Copyright (C) Andrew Tridgell 1994-1995
  6716. +   Copyright (C) Andrew Tridgell 1994-1996
  6717.     
  6718.     This program is free software; you can redistribute it and/or modify
  6719.     it under the terms of the GNU General Public License as published by
  6720. @@ -18,6 +18,8 @@
  6721.     along with this program; if not, write to the Free Software
  6722.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  6723.     
  6724. +   Module name: nameresp.c
  6725. +
  6726.  */
  6727.  
  6728.  #include "includes.h"
  6729. @@ -25,214 +27,192 @@
  6730.  extern int ClientNMB;
  6731.  extern int ClientDGRAM;
  6732.  
  6733. -/* this is our initiated name query response database */
  6734. -struct name_response_record *nameresponselist = NULL;
  6735. +extern struct subnet_record *subnetlist;
  6736.  
  6737.  extern int DEBUGLEVEL;
  6738.  
  6739. -static uint16 name_trn_id=0;
  6740. -BOOL CanRecurse = True;
  6741.  extern pstring scope;
  6742. -extern pstring myname;
  6743.  extern struct in_addr ipzero;
  6744. +extern struct in_addr ipgrp;
  6745.  
  6746.  
  6747.  /***************************************************************************
  6748. -  add an initated name query  into the list
  6749. +  deals with an entry before it dies
  6750.    **************************************************************************/
  6751. -extern void add_response_record(struct name_response_record *n)
  6752. +static void dead_netbios_entry(struct subnet_record *d,
  6753. +                struct response_record *n)
  6754.  {
  6755. -  struct name_response_record *n2;
  6756. +  DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
  6757. +       inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
  6758.  
  6759. -  if (!nameresponselist)
  6760. -    {
  6761. -      nameresponselist = n;
  6762. -      n->prev = NULL;
  6763. -      n->next = NULL;
  6764. -      return;
  6765. +  debug_state_type(n->state);
  6766. +
  6767. +  switch (n->state)
  6768. +  {
  6769. +    case NAME_QUERY_CONFIRM:
  6770. +    {
  6771. +        if (!lp_wins_support()) return; /* only if we're a WINS server */
  6772. +
  6773. +        if (n->num_msgs == 0)
  6774. +        {
  6775. +            /* oops. name query had no response. check that the name is
  6776. +               unique and then remove it from our WINS database */
  6777. +
  6778. +            /* IMPORTANT: see query_refresh_names() */
  6779. +
  6780. +            if ((!NAME_GROUP(n->nb_flags)))
  6781. +            {
  6782. +                struct subnet_record *d1 = find_subnet(ipgrp);
  6783. +                if (d1)
  6784. +                {
  6785. +                    /* remove the name that had been registered with us,
  6786. +                       and we're now getting no response when challenging.
  6787. +                       see rfc1001.txt 15.5.2
  6788. +                     */
  6789. +                    remove_netbios_name(d1, n->name.name, n->name.name_type,
  6790. +                                    REGISTER, n->send_ip);
  6791. +                }
  6792. +            }
  6793. +        }
  6794. +        break;
  6795.      }
  6796. -  
  6797. -  for (n2 = nameresponselist; n2->next; n2 = n2->next) ;
  6798. -  
  6799. -  n2->next = n;
  6800. -  n->next = NULL;
  6801. -  n->prev = n2;
  6802. -}
  6803.  
  6804. +    case NAME_QUERY_MST_CHK:
  6805. +    {
  6806. +      /* if no response received, the master browser must have gone
  6807. +         down on that subnet, without telling anyone. */
  6808.  
  6809. -/*******************************************************************
  6810. -  remove old name response entries
  6811. -  ******************************************************************/
  6812. -void expire_netbios_response_entries(time_t t)
  6813. -{
  6814. -  struct name_response_record *n;
  6815. -  struct name_response_record *nextn;
  6816. +      /* IMPORTANT: see response_netbios_packet() */
  6817.  
  6818. -  for (n = nameresponselist; n; n = nextn)
  6819. -    {
  6820. -      if (n->start_time < t)
  6821. +      if (n->num_msgs == 0)
  6822. +          browser_gone(n->name.name, n->send_ip);
  6823. +      break;
  6824. +    }
  6825. +
  6826. +    case NAME_RELEASE:
  6827.      {
  6828. -      DEBUG(3,("Removing dead name query for %s %s (num_msgs=%d)\n",
  6829. -           inet_ntoa(n->to_ip), namestr(&n->name), n->num_msgs));
  6830. +      /* if no response received, it must be OK for us to release the
  6831. +         name. nobody objected (including a potentially dead or deaf
  6832. +         WINS server) */
  6833.  
  6834. -      if (n->cmd_type == CHECK_MASTER)
  6835. -        {
  6836. -          /* if no response received, the master browser must have gone */
  6837. -          if (n->num_msgs == 0)
  6838. -        browser_gone(n->name.name, n->to_ip);
  6839. -        }
  6840. -      
  6841. -      nextn = n->next;
  6842. -      
  6843. -      if (n->prev) n->prev->next = n->next;
  6844. -      if (n->next) n->next->prev = n->prev;
  6845. -      
  6846. -      if (nameresponselist == n) nameresponselist = n->next; 
  6847. -      
  6848. -      free(n);
  6849. +      /* IMPORTANT: see response_name_release() */
  6850. +
  6851. +      if (ismyip(n->send_ip))
  6852. +      {
  6853. +        name_unregister_work(d,n->name.name,n->name.name_type);
  6854. +      }
  6855. +      if (!n->bcast)
  6856. +      {
  6857. +         DEBUG(0,("WINS server did not respond to name release!\n"));
  6858. +         /* XXXX whoops. we have problems. must deal with this */
  6859. +      }
  6860. +      break;
  6861.      }
  6862. -      else
  6863. +
  6864. +    case NAME_REGISTER_CHALLENGE:
  6865.      {
  6866. -      nextn = n->next;
  6867. +        /* name challenge: no reply. we can reply to the person that
  6868. +           wanted the unique name and tell them that they can have it
  6869. +         */
  6870. +
  6871. +        add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
  6872. +                        n->nb_flags, GET_TTL(0),
  6873. +                        n->reply_to_ip, False, n->reply_to_ip);
  6874. +
  6875. +      if (!n->bcast)
  6876. +      {
  6877. +         DEBUG(1,("WINS server did not respond to name registration!\n"));
  6878. +         /* XXXX whoops. we have problems. must deal with this */
  6879. +      }
  6880. +      break;
  6881.      }
  6882. -    }
  6883. -}
  6884.  
  6885. +    case NAME_REGISTER:
  6886. +    {
  6887. +      /* if no response received, and we are using a broadcast registration
  6888. +         method, it must be OK for us to register the name: nobody objected 
  6889. +         on that subnet. if we are using a WINS server, then the WINS
  6890. +         server must be dead or deaf.
  6891. +       */
  6892. +      if (n->bcast)
  6893. +      {
  6894. +        /* broadcast method: implicit acceptance of the name registration
  6895. +           by not receiving any objections. */
  6896.  
  6897. -/****************************************************************************
  6898. -  reply to a netbios name packet 
  6899. -  ****************************************************************************/
  6900. -void reply_netbios_packet(struct packet_struct *p1,int trn_id,int rcode,
  6901. -              int opcode,BOOL recurse,struct nmb_name *rr_name,
  6902. -              int rr_type,int rr_class,int ttl,char *data,int len)
  6903. -{
  6904. -  struct packet_struct p;
  6905. -  struct nmb_packet *nmb = &p.packet.nmb;
  6906. -  struct res_rec answers;
  6907. -  char *packet_type = "unknown";
  6908. -  
  6909. -  p = *p1;
  6910. +        /* IMPORTANT: see response_name_reg() */
  6911.  
  6912. -  if (rr_type == NMB_STATUS) packet_type = "nmb_status";
  6913. -  if (rr_type == NMB_QUERY ) packet_type = "nmb_query";
  6914. -  if (rr_type == NMB_REG   ) packet_type = "nmb_reg";
  6915. -  if (rr_type == NMB_REL   ) packet_type = "nmb_rel";
  6916. -  
  6917. -  DEBUG(4,("replying netbios packet: %s %s\n",
  6918. -       packet_type, namestr(rr_name), inet_ntoa(p.ip)));
  6919. +        name_register_work(d,n->name.name,n->name.name_type,
  6920. +                n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
  6921. +      }
  6922. +      else
  6923. +      {
  6924. +        /* received no response. rfc1001.txt states that after retrying,
  6925. +           we should assume the WINS server is dead, and fall back to
  6926. +           broadcasting (see bits about M nodes: can't find any right
  6927. +           now) */
  6928. +        
  6929. +        DEBUG(1,("WINS server did not respond to name registration!\n"));
  6930. +        /* XXXX whoops. we have problems. must deal with this */
  6931. +      }
  6932. +      break;
  6933. +    }
  6934.  
  6935. -  nmb->header.name_trn_id = trn_id;
  6936. -  nmb->header.opcode = opcode;
  6937. -  nmb->header.response = True;
  6938. -  nmb->header.nm_flags.bcast = False;
  6939. -  nmb->header.nm_flags.recursion_available = recurse;
  6940. -  nmb->header.nm_flags.recursion_desired = True;
  6941. -  nmb->header.nm_flags.trunc = False;
  6942. -  nmb->header.nm_flags.authoritative = True;
  6943. -  
  6944. -  nmb->header.qdcount = 0;
  6945. -  nmb->header.ancount = 1;
  6946. -  nmb->header.nscount = 0;
  6947. -  nmb->header.arcount = 0;
  6948. -  nmb->header.rcode = 0;
  6949. -  
  6950. -  bzero((char*)&nmb->question,sizeof(nmb->question));
  6951. -  
  6952. -  nmb->answers = &answers;
  6953. -  bzero((char*)nmb->answers,sizeof(*nmb->answers));
  6954. -  
  6955. -  nmb->answers->rr_name  = *rr_name;
  6956. -  nmb->answers->rr_type  = rr_type;
  6957. -  nmb->answers->rr_class = rr_class;
  6958. -  nmb->answers->ttl      = ttl;
  6959. -  
  6960. -  if (data && len)
  6961. -    {
  6962. -      nmb->answers->rdlength = len;
  6963. -      memcpy(nmb->answers->rdata, data, len);
  6964. -    }
  6965. -  
  6966. -  p.packet_type = NMB_PACKET;
  6967. -  
  6968. -  debug_nmb_packet(&p);
  6969. -  
  6970. -  send_packet(&p);
  6971. +    default:
  6972. +    {
  6973. +      /* nothing to do but delete the dead expected-response structure */
  6974. +      /* this is normal. */
  6975. +      break;
  6976. +    }
  6977. +  }
  6978.  }
  6979.  
  6980.  
  6981. -/****************************************************************************
  6982. -  initiate a netbios packet
  6983. -  ****************************************************************************/
  6984. -uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type,
  6985. -                   int nb_flags,BOOL bcast,BOOL recurse,
  6986. -                   struct in_addr to_ip)
  6987. -{
  6988. -  struct packet_struct p;
  6989. -  struct nmb_packet *nmb = &p.packet.nmb;
  6990. -  struct res_rec additional_rec;
  6991. -  char *packet_type = "unknown";
  6992. -  int opcode = -1;
  6993. -
  6994. -  if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
  6995. -  if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
  6996. -  if (quest_type == NMB_REG   ) { packet_type = "nmb_reg"; opcode = 5; }
  6997. -  if (quest_type == NMB_REL   ) { packet_type = "nmb_rel"; opcode = 6; }
  6998. -  
  6999. -  DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
  7000. -       packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
  7001. +/*******************************************************************
  7002. +  remove old name response entries
  7003.  
  7004. -  if (opcode == -1) return False;
  7005. +  XXXX retry code needs to be added, including a retry wait period and a count
  7006. +       see name_query() and name_status() for suggested implementation.
  7007.  
  7008. -  bzero((char *)&p,sizeof(p));
  7009. +  ******************************************************************/
  7010. +void expire_netbios_response_entries()
  7011. +{
  7012. +  struct subnet_record *d;
  7013.  
  7014. -  if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + 
  7015. -    (getpid()%(unsigned)100);
  7016. -  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
  7017. -
  7018. -  nmb->header.name_trn_id = name_trn_id;
  7019. -  nmb->header.opcode = opcode;
  7020. -  nmb->header.response = False;
  7021. -  nmb->header.nm_flags.bcast = bcast;
  7022. -  nmb->header.nm_flags.recursion_available = CanRecurse;
  7023. -  nmb->header.nm_flags.recursion_desired = recurse;
  7024. -  nmb->header.nm_flags.trunc = False;
  7025. -  nmb->header.nm_flags.authoritative = False;
  7026. -  nmb->header.rcode = 0;
  7027. -  nmb->header.qdcount = 1;
  7028. -  nmb->header.ancount = 0;
  7029. -  nmb->header.nscount = 0;
  7030. -  nmb->header.arcount = (quest_type==NMB_REG || quest_type==NMB_REL) ? 1 : 0;
  7031. -  
  7032. -  make_nmb_name(&nmb->question.question_name,name,name_type,scope);
  7033. -  
  7034. -  nmb->question.question_type = quest_type;
  7035. -  nmb->question.question_class = 0x1;
  7036. -  
  7037. -  if (quest_type == NMB_REG || quest_type == NMB_REL)
  7038. +  for (d = subnetlist; d; d = d->next)
  7039. +  {
  7040. +    struct response_record *n, *nextn;
  7041. +
  7042. +    for (n = d->responselist; n; n = nextn)
  7043.      {
  7044. -      nmb->additional = &additional_rec;
  7045. -      bzero((char *)nmb->additional,sizeof(*nmb->additional));
  7046. -      
  7047. -      nmb->additional->rr_name  = nmb->question.question_name;
  7048. -      nmb->additional->rr_type  = nmb->question.question_type;
  7049. -      nmb->additional->rr_class = nmb->question.question_class;
  7050. -      
  7051. -      nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0;
  7052. -      nmb->additional->rdlength = 6;
  7053. -      nmb->additional->rdata[0] = nb_flags;
  7054. -      putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
  7055. +      nextn = n->next;
  7056. +
  7057. +      if (n->repeat_time <= time(NULL))
  7058. +      {
  7059. +          if (n->repeat_count > 0)
  7060. +          {
  7061. +            /* resend the entry */
  7062. +              initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
  7063. +                        n->name.name, n->name.name_type,
  7064. +                      n->nb_flags, n->bcast, n->recurse, n->send_ip);
  7065. +
  7066. +            n->repeat_time += n->repeat_interval; /* XXXX ms needed */
  7067. +            n->repeat_count--;
  7068. +
  7069. +          }
  7070. +          else
  7071. +          {
  7072. +              DEBUG(4,("timeout response %d for %s %s\n",
  7073. +                        n->response_id, namestr(&n->name),
  7074. +                        inet_ntoa(n->send_ip)));
  7075. +
  7076. +              dead_netbios_entry    (d,n); /* process the non-response */
  7077. +              remove_response_record(d,n); /* remove the non-response */
  7078. +
  7079. +              continue;
  7080. +           }
  7081. +      }
  7082.      }
  7083. -  
  7084. -  p.ip = to_ip;
  7085. -  p.port = NMB_PORT;
  7086. -  p.fd = fd;
  7087. -  p.timestamp = time(NULL);
  7088. -  p.packet_type = NMB_PACKET;
  7089. -  
  7090. -  if (!send_packet(&p)) 
  7091. -    return(0);
  7092. -  
  7093. -  return(name_trn_id);
  7094. +  }
  7095.  }
  7096.  
  7097.  
  7098. @@ -241,10 +221,18 @@
  7099.    name server instead, if it exists. if wins is false, and there has been no
  7100.    WINS server specified, the packet will NOT be sent.
  7101.    ****************************************************************************/
  7102. -void queue_netbios_pkt_wins(int fd,int quest_type,enum cmd_type cmd,
  7103. -                char *name,int name_type,int nb_flags,
  7104. -                BOOL bcast,BOOL recurse,struct in_addr to_ip)
  7105. -{
  7106. +struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
  7107. +                int fd,int quest_type,enum state_type state,
  7108. +                char *name,int name_type,int nb_flags, time_t ttl,
  7109. +                BOOL bcast,BOOL recurse,
  7110. +                struct in_addr send_ip, struct in_addr reply_to_ip)
  7111. +{
  7112. +  /* XXXX note: please see rfc1001.txt section 10 for details on this
  7113. +     function: it is currently inappropriate to use this - it will do
  7114. +     for now - once there is a clarification of B, M and P nodes and
  7115. +     which one samba is supposed to be
  7116. +   */
  7117. +
  7118.    if ((!lp_wins_support()) && (*lp_wins_server()))
  7119.      {
  7120.        /* samba is not a WINS server, and we are using a WINS server */
  7121. @@ -254,7 +242,7 @@
  7122.        if (!zero_ip(wins_ip))
  7123.      {
  7124.        bcast = False;
  7125. -      to_ip = wins_ip;
  7126. +      send_ip = wins_ip;
  7127.      }
  7128.        else
  7129.      {
  7130. @@ -264,38 +252,11 @@
  7131.      }
  7132.      }
  7133.  
  7134. -  if (zero_ip(to_ip)) return;
  7135. -
  7136. -  queue_netbios_packet(fd, quest_type, cmd, 
  7137. -               name, name_type, nb_flags,
  7138. -               bcast, recurse, to_ip);
  7139. -}
  7140. -
  7141. -/****************************************************************************
  7142. -  create a name query response record
  7143. -  **************************************************************************/
  7144. -static struct name_response_record *
  7145. -make_name_query_record(enum cmd_type cmd,int id,int fd,char *name,int type,
  7146. -               BOOL bcast,BOOL recurse,struct in_addr ip)
  7147. -{
  7148. -  struct name_response_record *n;
  7149. -    
  7150. -  if (!name || !name[0]) return NULL;
  7151. -    
  7152. -  if (!(n = (struct name_response_record *)malloc(sizeof(*n)))) 
  7153. -    return(NULL);
  7154. -
  7155. -  n->response_id = id;
  7156. -  n->cmd_type = cmd;
  7157. -  n->fd = fd;
  7158. -  make_nmb_name(&n->name, name, type, scope);
  7159. -  n->bcast = bcast;
  7160. -  n->recurse = recurse;
  7161. -  n->to_ip = ip;
  7162. -  n->start_time = time(NULL);
  7163. -  n->num_msgs = 0;
  7164. +  if (zero_ip(send_ip)) return NULL;
  7165.  
  7166. -  return n;
  7167. +  return queue_netbios_packet(d,fd, quest_type, state, 
  7168. +               name, name_type, nb_flags, ttl,
  7169. +               bcast, recurse, send_ip, reply_to_ip);
  7170.  }
  7171.  
  7172.  
  7173. @@ -305,310 +266,33 @@
  7174.    master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
  7175.    complete lists across a wide area network
  7176.    ****************************************************************************/
  7177. -void queue_netbios_packet(int fd,int quest_type,enum cmd_type cmd,char *name,
  7178. -              int name_type,int nb_flags,BOOL bcast,BOOL recurse,
  7179. -              struct in_addr to_ip)
  7180. -{
  7181. -  uint16 id = initiate_netbios_packet(fd, quest_type, name, name_type,
  7182. -                      nb_flags, bcast, recurse, to_ip);
  7183. -  struct name_response_record *n;
  7184. -
  7185. -  if (id == 0) return;
  7186. -  
  7187. -  if ((n = 
  7188. -       make_name_query_record(cmd,id,fd,name,name_type,bcast,recurse,to_ip)))
  7189. -    {
  7190. -      add_response_record(n);
  7191. -    }
  7192. -}
  7193. -
  7194. -
  7195. -/****************************************************************************
  7196. -  find a response in the name query response list
  7197. -  **************************************************************************/
  7198. -struct name_response_record *find_name_query(uint16 id)
  7199. -{   
  7200. -  struct name_response_record *n;
  7201. -
  7202. -  for (n = nameresponselist; n; n = n->next)
  7203. -    {
  7204. -      if (n->response_id == id)    {
  7205. -    return n;
  7206. -      }
  7207. -    }
  7208. -
  7209. -  return NULL;
  7210. -}
  7211. -
  7212. -
  7213. -/*******************************************************************
  7214. -  the global packet linked-list. incoming entries are added to the
  7215. -  end of this list.  it is supposed to remain fairly short so we
  7216. -  won't bother with an end pointer.
  7217. -  ******************************************************************/
  7218. -static struct packet_struct *packet_queue = NULL;
  7219. -
  7220. -/*******************************************************************
  7221. -  queue a packet into the packet queue
  7222. -  ******************************************************************/
  7223. -void queue_packet(struct packet_struct *packet)
  7224. -{
  7225. -  struct packet_struct *p;
  7226. -
  7227. -  if (!packet_queue) {
  7228. -    packet->prev = NULL;
  7229. -    packet->next = NULL;
  7230. -    packet_queue = packet;
  7231. -    return;
  7232. +struct response_record *queue_netbios_packet(struct subnet_record *d,
  7233. +            int fd,int quest_type,enum state_type state,char *name,
  7234. +            int name_type,int nb_flags, time_t ttl,
  7235. +                BOOL bcast,BOOL recurse,
  7236. +                struct in_addr send_ip, struct in_addr reply_to_ip)
  7237. +{
  7238. +  struct in_addr wins_ip = ipgrp;
  7239. +  struct response_record *n;
  7240. +  uint16 id = 0xffff;
  7241. +
  7242. +  /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
  7243. +  if (ip_equal(wins_ip, send_ip)) return NULL;
  7244. +
  7245. +  initiate_netbios_packet(&id, fd, quest_type, name, name_type,
  7246. +                      nb_flags, bcast, recurse, send_ip);
  7247. +
  7248. +  if (id == 0xffff) {
  7249. +    DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
  7250. +    return NULL;
  7251.    }
  7252.    
  7253. -  /* find the bottom */
  7254. -  for (p=packet_queue;p->next;p=p->next) ;
  7255. -
  7256. -  p->next = packet;
  7257. -  packet->next = NULL;
  7258. -  packet->prev = p;
  7259. -}
  7260. -
  7261. -/*******************************************************************
  7262. -  run elements off the packet queue till its empty
  7263. -  ******************************************************************/
  7264. -void run_packet_queue()
  7265. -{
  7266. -  struct packet_struct *p;
  7267. -
  7268. -  while ((p=packet_queue))
  7269. +  if ((n = make_response_queue_record(state,id,fd,
  7270. +                        quest_type,name,name_type,nb_flags,ttl,
  7271. +                        bcast,recurse,send_ip,reply_to_ip)))
  7272.      {
  7273. -      switch (p->packet_type)
  7274. -    {
  7275. -    case NMB_PACKET:
  7276. -      process_nmb(p);
  7277. -      break;
  7278. -      
  7279. -    case DGRAM_PACKET:
  7280. -      process_dgram(p);
  7281. -      break;
  7282. -    }
  7283. -      
  7284. -      packet_queue = packet_queue->next;
  7285. -      if (packet_queue) packet_queue->prev = NULL;
  7286. -      free_packet(p);
  7287. +      add_response_record(d,n);
  7288. +      return n;
  7289.      }
  7290. +   return NULL;
  7291.  }
  7292. -
  7293. -/****************************************************************************
  7294. -  listens for NMB or DGRAM packets, and queues them
  7295. -  ***************************************************************************/
  7296. -void listen_for_packets(BOOL run_election)
  7297. -{
  7298. -  fd_set fds;
  7299. -  int selrtn;
  7300. -  struct timeval timeout;
  7301. -
  7302. -  FD_ZERO(&fds);
  7303. -  FD_SET(ClientNMB,&fds);
  7304. -  FD_SET(ClientDGRAM,&fds);
  7305. -
  7306. -  /* during elections we need to send election packets at one
  7307. -     second intervals */
  7308. -
  7309. -  timeout.tv_sec = run_election ? 1 : NMBD_SELECT_LOOP;
  7310. -  timeout.tv_usec = 0;
  7311. -
  7312. -  selrtn = sys_select(&fds,&timeout);
  7313. -
  7314. -  if (FD_ISSET(ClientNMB,&fds))
  7315. -    {
  7316. -      struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
  7317. -      if (packet) {
  7318. -#if 1
  7319. -    if (ismyip(packet->ip) &&
  7320. -        (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
  7321. -      DEBUG(5,("discarding own packet from %s:%d\n",
  7322. -           inet_ntoa(packet->ip),packet->port));      
  7323. -      free_packet(packet);
  7324. -    } else 
  7325. -#endif
  7326. -      {
  7327. -        queue_packet(packet);
  7328. -      }
  7329. -      }
  7330. -    }
  7331. -
  7332. -  if (FD_ISSET(ClientDGRAM,&fds))
  7333. -    {
  7334. -      struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
  7335. -      if (packet) {
  7336. -#if 1
  7337. -    if (ismyip(packet->ip) &&
  7338. -          (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
  7339. -      DEBUG(5,("discarding own packet from %s:%d\n",
  7340. -           inet_ntoa(packet->ip),packet->port));      
  7341. -      free_packet(packet);
  7342. -    } else
  7343. -#endif 
  7344. -      {
  7345. -        queue_packet(packet);
  7346. -      }
  7347. -      }
  7348. -    }
  7349. -}
  7350. -
  7351. -
  7352. -
  7353. -/****************************************************************************
  7354. -interpret a node status response. this is pretty hacked: we need two bits of
  7355. -info. a) the name of the workgroup b) the name of the server. it will also
  7356. -add all the names it finds into the namelist.
  7357. -****************************************************************************/
  7358. -BOOL interpret_node_status(char *p, struct nmb_name *name,int t,
  7359. -               char *serv_name, struct in_addr ip)
  7360. -{
  7361. -  int level = t==0x20 ? 4 : 0;
  7362. -  int numnames = CVAL(p,0);
  7363. -  BOOL found = False;
  7364. -
  7365. -  DEBUG(level,("received %d names\n",numnames));
  7366. -
  7367. -  p += 1;
  7368. -
  7369. -  if (serv_name) *serv_name = 0;
  7370. -
  7371. -  while (numnames--)
  7372. -    {
  7373. -      char qname[17];
  7374. -      int type;
  7375. -      fstring flags;
  7376. -      int nb_flags;
  7377. -      
  7378. -      BOOL group = False;
  7379. -      BOOL add   = False;
  7380. -      
  7381. -      *flags = 0;
  7382. -      
  7383. -      StrnCpy(qname,p,15);
  7384. -      type = CVAL(p,15);
  7385. -      nb_flags = p[16];
  7386. -      trim_string(qname,NULL," ");
  7387. -      
  7388. -      p += 18;
  7389. -      
  7390. -      if (NAME_GROUP    (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
  7391. -      if (NAME_BFLAG    (nb_flags)) { strcat(flags,"B "); }
  7392. -      if (NAME_PFLAG    (nb_flags)) { strcat(flags,"P "); }
  7393. -      if (NAME_MFLAG    (nb_flags)) { strcat(flags,"M "); }
  7394. -      if (NAME__FLAG    (nb_flags)) { strcat(flags,"_ "); }
  7395. -      if (NAME_DEREG    (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
  7396. -      if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
  7397. -      if (NAME_ACTIVE   (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
  7398. -      if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
  7399. -      
  7400. -      /* might as well update our namelist while we're at it */
  7401. -      if (add)
  7402. -    {
  7403. -      struct in_addr nameip;
  7404. -      enum name_source src;
  7405. -      
  7406. -      if (ismyip(ip)) {
  7407. -        nameip = ipzero;
  7408. -        src = SELF;
  7409. -      } else {
  7410. -        nameip = ip;
  7411. -        src = STATUS_QUERY;
  7412. -      }
  7413. -      add_netbios_entry(qname,type,nb_flags,2*60*60,src,nameip,True);
  7414. -    } 
  7415. -
  7416. -      /* we want the server name */
  7417. -      if (serv_name && !*serv_name && !group && t == 0)
  7418. -    {
  7419. -      StrnCpy(serv_name,qname,15);
  7420. -      serv_name[15] = 0;
  7421. -    }
  7422. -      
  7423. -      /* looking for a name and type? */
  7424. -      if (name && !found && (t == type))
  7425. -    {
  7426. -      /* take a guess at some of the name types we're going to ask for.
  7427. -         evaluate whether they are group names or no... */
  7428. -      if (((t == 0x1b || t == 0x1d             ) && !group) ||
  7429. -          ((t == 0x20 || t == 0x1c || t == 0x1e) &&  group))
  7430. -        {
  7431. -          found = True;
  7432. -          make_nmb_name(name,qname,type,scope);
  7433. -        }
  7434. -    }
  7435. -      
  7436. -      DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
  7437. -    }
  7438. -  DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
  7439. -           IVAL(p,20),IVAL(p,24)));
  7440. -  return found;
  7441. -}
  7442. -
  7443. -
  7444. -/****************************************************************************
  7445. -  construct and send a netbios DGRAM
  7446. -
  7447. -  Note that this currently sends all answers to port 138. thats the
  7448. -  wrong things to do! I should send to the requestors port. XXX
  7449. -  **************************************************************************/
  7450. -BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
  7451. -             char *dstname,int src_type,int dest_type,
  7452. -             struct in_addr dest_ip,struct in_addr src_ip)
  7453. -{
  7454. -  struct packet_struct p;
  7455. -  struct dgram_packet *dgram = &p.packet.dgram;
  7456. -  char *ptr,*p2;
  7457. -  char tmp[4];
  7458. -
  7459. -  bzero((char *)&p,sizeof(p));
  7460. -
  7461. -  dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
  7462. -  dgram->header.flags.node_type = M_NODE;
  7463. -  dgram->header.flags.first = True;
  7464. -  dgram->header.flags.more = False;
  7465. -  dgram->header.dgm_id = name_trn_id++;
  7466. -  dgram->header.source_ip = src_ip;
  7467. -  dgram->header.source_port = DGRAM_PORT;
  7468. -  dgram->header.dgm_length = 0; /* let build_dgram() handle this */
  7469. -  dgram->header.packet_offset = 0;
  7470. -  
  7471. -  make_nmb_name(&dgram->source_name,srcname,src_type,scope);
  7472. -  make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
  7473. -
  7474. -  ptr = &dgram->data[0];
  7475. -
  7476. -  /* now setup the smb part */
  7477. -  ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
  7478. -  memcpy(tmp,ptr,4);
  7479. -  set_message(ptr,17,17 + len,True);
  7480. -  memcpy(ptr,tmp,4);
  7481. -
  7482. -  CVAL(ptr,smb_com) = SMBtrans;
  7483. -  SSVAL(ptr,smb_vwv1,len);
  7484. -  SSVAL(ptr,smb_vwv11,len);
  7485. -  SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
  7486. -  SSVAL(ptr,smb_vwv13,3);
  7487. -  SSVAL(ptr,smb_vwv14,1);
  7488. -  SSVAL(ptr,smb_vwv15,1);
  7489. -  SSVAL(ptr,smb_vwv16,2);
  7490. -  p2 = smb_buf(ptr);
  7491. -  strcpy(p2,mailslot);
  7492. -  p2 = skip_string(p2,1);
  7493. -
  7494. -  memcpy(p2,buf,len);
  7495. -  p2 += len;
  7496. -
  7497. -  dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
  7498. -
  7499. -  p.ip = dest_ip;
  7500. -  p.port = DGRAM_PORT;
  7501. -  p.fd = ClientDGRAM;
  7502. -  p.timestamp = time(NULL);
  7503. -  p.packet_type = DGRAM_PACKET;
  7504. -
  7505. -  return(send_packet(&p));
  7506. -}
  7507. -
  7508. -
  7509. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameresp.doc samba-1.9.16alpha11/source/nameresp.doc
  7510. --- samba-1.9.16alpha10/source/nameresp.doc    Thu Jan  1 10:00:00 1970
  7511. +++ samba-1.9.16alpha11/source/nameresp.doc    Thu Jul 18 20:53:15 1996
  7512. @@ -0,0 +1,151 @@
  7513. +the netbios expected response code is a key part of samba's NetBIOS
  7514. +handling capabilities. it allows samba to carry on dealing with
  7515. +other things while expecting a response from one or more hosts.
  7516. +
  7517. +this allows samba to simultaneously deal with registering its names
  7518. +with another WINS server, register its names on its local subnets,
  7519. +query any hosts that have registered with samba in its capacity as
  7520. +a WINS server, and at a later date it will be also be able handle
  7521. +END-NODE CHALLENGES (see rfc1001.txt 15.2.2.2 and 15.2.2.3 - secured
  7522. +NBNS functionality).
  7523. +
  7524. +all at once!
  7525. +
  7526. +when a netbios packet is sent out by samba and it expects a response,
  7527. +a record of all the relevant information is kept (most importantly,
  7528. +the unique transaction id associated which will come back to us in
  7529. +a response packet is recorded, and also recorded is the reason that
  7530. +the original packet was sent out by samba in the first place!).
  7531. +
  7532. +if a response is received, then the unique transaction identifier 
  7533. +returned in the response packet is searched for in the expected
  7534. +response records. the record indicates why the initial request was
  7535. +made (and therefore the type of response can be verified) and
  7536. +appropriate action can be taken.
  7537. +
  7538. +when no responses, after a number of retries, are not received, then
  7539. +samba may take appropriate action. this is a crucial part of samba's
  7540. +operation: for a key number of NetBIOS operations, no response is an
  7541. +implicit positive response.
  7542. +
  7543. +module nameresp deals with the initial transmission, re-transmission
  7544. +and time-out of netbios response records.
  7545. +
  7546. +module namedbresp deals with the maintenance of the list of expected
  7547. +responses - creation, finding and removal.
  7548. +
  7549. +
  7550. +/*************************************************************************
  7551. +  queue_netbios_packet()
  7552. +  *************************************************************************/
  7553. +
  7554. +this function is responsible for sending out a netbios packet, and then
  7555. +making a record of the information that was sent out. a response will
  7556. +be expected later (or not, as the case may be).
  7557. +
  7558. +if a response is received, response_netbios_packet() will deal with it.
  7559. +otherwise, it will be dealt with in expire_netbios_response_entries().
  7560. +
  7561. +
  7562. +/*************************************************************************
  7563. +  queue_netbios_pkt_wins()
  7564. +  *************************************************************************/
  7565. +
  7566. +this function is a wrapper around queue_netbios_packet(). there is
  7567. +some confusion about B, M and P nodes (see rfc1001.txt section 10) -
  7568. +confusion introduced by luke :-) - which needs sorting out.
  7569. +
  7570. +for example, rfc1001.txt 15.2.3 - an M node must attempt to register a
  7571. +name first as a B node, then attempt to register as an M node. negative
  7572. +responses on either of these attempts is a failure to register the
  7573. +name.
  7574. +
  7575. +this is NOT the case with a P node.
  7576. +
  7577. +
  7578. +/*************************************************************************
  7579. +  expire_netbios_response_entries()
  7580. +  *************************************************************************/
  7581. +
  7582. +this function is responsible for dealing with queued response records
  7583. +that have not received a response packet matching their unique
  7584. +transaction id.
  7585. +
  7586. +if the retry count for any record is non-zero, and its time-out period
  7587. +has expired, the retry count is reduced, the time-out period is stepped
  7588. +forward and the packet is re-transmitted (from the information stored
  7589. +in the queued response record) with the same unique transaction id of
  7590. +the initial attempt at soliciting a response.
  7591. +
  7592. +if the retry count is zero, then the packet is assumed to have expired.
  7593. +dead_netbios_entry() is called to deal with the possibility of an error
  7594. +or a problem (or in certain instances, no answer is an implicit
  7595. +positive response!).
  7596. +
  7597. +the expected response record is then deleted, and the number of expected
  7598. +responses reduced. when this count gets to zero, listen_for_packets()
  7599. +will no longer time-out for 1 second on account of expecting response
  7600. +packets.
  7601. +
  7602. +
  7603. +/*************************************************************************
  7604. +  dead_netbios_entry()
  7605. +  *************************************************************************/
  7606. +
  7607. +this function is responsible for dealing with the case when a NetBIOS
  7608. +response to a packet sent out by samba was not received. for certain
  7609. +transactions, this may be normal. for others, under certain conditions
  7610. +it may constitute either an error or a problem with or failure of one
  7611. +or more hosts.
  7612. +
  7613. +- NAME_QUERY_CONFIRM
  7614. +
  7615. +when a samba 'state' of type NAME_QUERY_CONFIRM is sent, a response
  7616. +may or may not be forthcoming. if no response is received to a unique
  7617. +name, then the record is removed from samba's WINS database. non-unique
  7618. +names are simply expected to die off on a time-to-live basis (see
  7619. +rfc1001.txt 15.1.3.4)
  7620. +
  7621. +query_refresh_names() issues this samba 'state'
  7622. +response_name_query_sync() deals with responses to NAME_QUERY_CONFIRM.
  7623. +
  7624. +- NAME_QUERY_MST_CHK
  7625. +
  7626. +when a samba 'state' of type NAME_QUERY_MST_CHK is sent, and a response
  7627. +is not received, this implies that a master browser will have failed.
  7628. +remedial action may need to be taken, for example if samba is a member
  7629. +of that workgroup and it is also a potential master browser it could
  7630. +force an election.
  7631. +
  7632. +check_master_browser() issues this samba 'state'.
  7633. +response_process() does nothing if a response is received. this is normal.
  7634. +
  7635. +- NAME_RELEASE
  7636. +
  7637. +when a samba 'state' of type NAME_RELEASE is sent, and a response is
  7638. +not received, it is assumed to be acceptable to release the name. if the
  7639. +original response was sent to another WINS server, then that WINS server
  7640. +may be inaccessible or may have failed. if so, then at a later date
  7641. +samba should take this into account (see rfc1001.txt 10.3).
  7642. +
  7643. +remove_name_entry() issues this samba 'state'
  7644. +response_name_rel() deals with responses to NAME_RELEASE.
  7645. +
  7646. +- NAME_REGISTER
  7647. +
  7648. +when a samba 'state' of type NAME_REGISTER is sent, and a response is
  7649. +not received, if the registration was done by broadcast, it is assumed
  7650. +that there are no objections to the registration of this name, and samba
  7651. +adds the name to the appropriate subnet record name database. if the
  7652. +registration was point-to-point (i.e with another WINS server) then that
  7653. +WINS server may be inaccessible or may have failed. if so, then at a later
  7654. +date samba should take this into account (see rfc1001.txt 10.3).
  7655. +
  7656. +add_my_name_entry() issues this samba 'state'
  7657. +response_name_reg() deals with responses to NAME_REGISTER.
  7658. +
  7659. +no action is taken for any other kinds of samba 'states' if a response
  7660. +is not received. this is not to say that action may not be appropriate,
  7661. +just that it's not been looked at yet :-)
  7662. +
  7663. +
  7664. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameserv.c samba-1.9.16alpha11/source/nameserv.c
  7665. --- samba-1.9.16alpha10/source/nameserv.c    Mon Jun 10 15:18:56 1996
  7666. +++ samba-1.9.16alpha11/source/nameserv.c    Thu Jul 18 20:53:15 1996
  7667. @@ -2,7 +2,7 @@
  7668.     Unix SMB/Netbios implementation.
  7669.     Version 1.9.
  7670.     NBT netbios routines and daemon - version 2
  7671. -   Copyright (C) Andrew Tridgell 1994-1995
  7672. +   Copyright (C) Andrew Tridgell 1994-1996
  7673.     
  7674.     This program is free software; you can redistribute it and/or modify
  7675.     it under the terms of the GNU General Public License as published by
  7676. @@ -18,225 +18,151 @@
  7677.     along with this program; if not, write to the Free Software
  7678.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  7679.     
  7680. +   Module name: nameserv.c
  7681. +
  7682.     Revision History:
  7683.  
  7684.     14 jan 96: lkcl@pires.co.uk
  7685.     added multiple workgroup domain master support
  7686.  
  7687. +   04 jul 96: lkcl@pires.co.uk
  7688. +   module nameserv contains name server management functions
  7689.  */
  7690.  
  7691.  #include "includes.h"
  7692.  
  7693.  extern int ClientNMB;
  7694. -extern int ClientDGRAM;
  7695.  
  7696.  extern int DEBUGLEVEL;
  7697.  
  7698.  extern pstring scope;
  7699. -extern BOOL CanRecurse;
  7700.  extern pstring myname;
  7701. +extern pstring ServerComment;
  7702.  extern struct in_addr ipzero;
  7703.  extern struct in_addr ipgrp;
  7704.  
  7705. -/* netbios names database */
  7706. -struct name_record *namelist;
  7707. -
  7708. -#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
  7709. +extern struct subnet_record *subnetlist;
  7710.  
  7711.  
  7712.  /****************************************************************************
  7713. -  true if two netbios names are equal
  7714. -****************************************************************************/
  7715. -static BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
  7716. -{
  7717. -  if (n1->name_type != n2->name_type) return(False);
  7718. -
  7719. -  return(strequal(n1->name,n2->name) && strequal(n1->scope,n2->scope));
  7720. -}
  7721. -
  7722. -/****************************************************************************
  7723. -  add a netbios name into the namelist
  7724. -  **************************************************************************/
  7725. -static void add_name(struct name_record *n)
  7726. -{
  7727. -  struct name_record *n2;
  7728. -
  7729. -  if (!namelist)
  7730. -  {
  7731. -    namelist = n;
  7732. -    n->prev = NULL;
  7733. -    n->next = NULL;
  7734. -    return;
  7735. -  }
  7736. +  remove an entry from the name list
  7737.  
  7738. -  for (n2 = namelist; n2->next; n2 = n2->next) ;
  7739. +  note: the name will _always_ be removed: it's just a matter of when.
  7740. +  XXXX at present, the name is removed _even_ if a WINS server says keep it.
  7741.  
  7742. -  n2->next = n;
  7743. -  n->next = NULL;
  7744. -  n->prev = n2;
  7745. -}
  7746. -
  7747. -/****************************************************************************
  7748. -  remove a name from the namelist. The pointer must be an element just 
  7749. -  retrieved
  7750. -  **************************************************************************/
  7751. -void remove_name(struct name_record *n)
  7752. +  ****************************************************************************/
  7753. +void remove_name_entry(struct subnet_record *d, char *name,int type)
  7754.  {
  7755. -  struct name_record *nlist = namelist;
  7756. +  /* XXXX BUG: if samba is offering WINS support, it should still broadcast
  7757. +      a de-registration packet to the local subnet before removing the
  7758. +      name from its local-subnet name database. */
  7759.  
  7760. -  while (nlist && nlist != n) nlist = nlist->next;
  7761. +  struct name_record n;
  7762. +  struct name_record *n2=NULL;
  7763. +      
  7764. +  make_nmb_name(&n.name,name,type,scope);
  7765.  
  7766. -  if (nlist)
  7767. +  if ((n2 = find_name_search(&d, &n.name, FIND_SELF, ipzero)))
  7768.    {
  7769. -    if (nlist->next) nlist->next->prev = nlist->prev;
  7770. -    if (nlist->prev) nlist->prev->next = nlist->next;
  7771. -    free(nlist);
  7772. -  }
  7773. -}
  7774. +    /* check name isn't already being de-registered */
  7775. +    if (NAME_DEREG(n2->nb_flags))
  7776. +      return;
  7777.  
  7778. +    /* mark the name as in the process of deletion. */
  7779. +    n2->nb_flags &= NB_DEREG;
  7780. +  }
  7781.  
  7782. -/****************************************************************************
  7783. -  find a name in the domain database namelist 
  7784. -  search can be:
  7785. -  FIND_SELF   - look for names the samba server has added for itself
  7786. -  FIND_GLOBAL - the name can be anyone. first look on the client's
  7787. -                subnet, then the server's subnet, then all subnets.
  7788. -  **************************************************************************/
  7789. -static struct name_record *find_name_search(struct nmb_name *name,
  7790. -                        enum name_search search,
  7791. -                        struct in_addr ip)
  7792. -{
  7793. -  struct name_record *ret;
  7794. -  
  7795. -  for (ret = namelist; ret; ret = ret->next)
  7796. +  if (ip_equal(d->bcast_ip, ipgrp))
  7797. +  {
  7798. +    if (lp_wins_support())
  7799.      {
  7800. -      if (!name_equal(&ret->name,name)) continue;
  7801. -
  7802. -      if (search == FIND_SELF && ret->source != SELF) continue;
  7803. -      
  7804. -      return ret;
  7805. +        /* we are a WINS server. */
  7806. +        /* XXXX assume that if we are a WINS server that we are therefore
  7807. +           not pointing to another WINS server as well. this may later NOT
  7808. +           actually be true
  7809. +         */
  7810. +        remove_netbios_name(d,name,type,SELF,ipzero);
  7811. +    }
  7812. +    else
  7813. +    {
  7814. +      /* not a WINS server: cannot just remove our own names: we have to
  7815. +         release them on the network first. ask permission from the WINS
  7816. +         server, or if no reply is received, then we can remove the name */
  7817. +
  7818. +        queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
  7819. +                 name, type, 0, 0,
  7820. +                 False, True, ipzero, ipzero);
  7821.      }
  7822. -  
  7823. -  return NULL;
  7824. +  }
  7825. +  else
  7826. +  {
  7827. +     /* local interface: cannot just remove our own names: we have to
  7828. +        release them on the network first. once no reply is received,
  7829. +        then we can remove the name. */
  7830. +
  7831. +     queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
  7832. +                 name, type, 0, 0,
  7833. +                 True, True, d->bcast_ip, d->bcast_ip);
  7834. +  }
  7835.  }
  7836.  
  7837.  
  7838.  /****************************************************************************
  7839. -  dump a copy of the name table
  7840. -  **************************************************************************/
  7841. -void dump_names(void)
  7842. -{
  7843. -  struct name_record *n;
  7844. -  time_t t = time(NULL);
  7845. -  
  7846. -  DEBUG(3,("Dump of local name table:\n"));
  7847. +  add an entry to the name list
  7848.    
  7849. -  for (n = namelist; n; n = n->next)
  7850. -    {
  7851. -      DEBUG(3,("%s %s TTL=%d NBFLAGS=%2x\n",
  7852. -           namestr(&n->name),
  7853. -           inet_ntoa(n->ip),
  7854. -           n->death_time?n->death_time-t:0,
  7855. -           n->nb_flags));
  7856. -    }
  7857. -}
  7858. -
  7859. +  big note: our name will _always_ be added (if there are no objections).
  7860. +  it's just a matter of when this will be done (e.g after a time-out).
  7861.  
  7862. -/****************************************************************************
  7863. -  remove an entry from the name list
  7864.    ****************************************************************************/
  7865. -void remove_netbios_name(char *name,int type, enum name_source source,
  7866. -             struct in_addr ip)
  7867. +void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
  7868.  {
  7869. -  struct nmb_name nn;
  7870. -  struct name_record *n;
  7871. -  
  7872. -  make_nmb_name(&nn, name, type, scope);
  7873. -  n = find_name_search(&nn, FIND_GLOBAL, ip);
  7874. -  
  7875. -  if (n && n->source == source) remove_name(n);
  7876. -}
  7877. +  BOOL re_reg = False;
  7878. +  struct nmb_name n;
  7879.  
  7880. +  if (!d) return;
  7881.  
  7882. -/****************************************************************************
  7883. -  add an entry to the name list
  7884. -  ****************************************************************************/
  7885. -struct name_record *add_netbios_entry(char *name, int type, int nb_flags, 
  7886. -                      int ttl,
  7887. -                      enum name_source source, 
  7888. -                      struct in_addr ip,
  7889. -                      BOOL new_only)
  7890. -{
  7891. -  struct name_record *n;
  7892. -  struct name_record *n2=NULL;
  7893. -
  7894. -  n = (struct name_record *)malloc(sizeof(*n));
  7895. -  if (!n) return(NULL);
  7896. +  /* not that it particularly matters, but if the SELF name already exists,
  7897. +     it must be re-registered, rather than just registered */
  7898.  
  7899. -  bzero((char *)n,sizeof(*n));
  7900. +  make_nmb_name(&n, name, type, scope);
  7901. +  if (find_name(d->namelist, &n, SELF))
  7902. +    re_reg = True;
  7903.  
  7904. -  make_nmb_name(&n->name,name,type,scope);
  7905. +  /* XXXX BUG: if samba is offering WINS support, it should still add the
  7906. +     name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
  7907. +     regarding the point about M-nodes. */
  7908.  
  7909. -  if ((n2 = find_name_search(&n->name, FIND_GLOBAL, new_only?ipzero:ip)))
  7910. +  if (ip_equal(d->bcast_ip, ipgrp))
  7911.    {
  7912. -    free(n);
  7913. -    if (new_only || (n2->source==SELF && source!=SELF)) return n2;
  7914. -    n = n2;
  7915. -  }
  7916. -
  7917. -  if (ttl) n->death_time = time(NULL)+ttl*3;
  7918. -  n->ip = ip;
  7919. -  n->nb_flags = nb_flags;
  7920. -  n->source = source;
  7921. -  
  7922. -  if (!n2) add_name(n);
  7923. -
  7924. -  DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
  7925. -            namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
  7926. -
  7927. -  return(n);
  7928. -}
  7929. -
  7930. -
  7931. -/****************************************************************************
  7932. -  remove an entry from the name list
  7933. -  ****************************************************************************/
  7934. -void remove_name_entry(char *name,int type)
  7935. -{
  7936. -  if (lp_wins_support())
  7937. +    if (lp_wins_support())
  7938.      {
  7939.        /* we are a WINS server. */
  7940. -      remove_netbios_name(name,type,SELF,ipzero);
  7941. +      /* XXXX assume that if we are a WINS server that we are therefore
  7942. +         not pointing to another WINS server as well. this may later NOT
  7943. +         actually be true
  7944. +       */
  7945. +
  7946. +      DEBUG(4,("samba as WINS server adding: "));
  7947. +      /* this will call add_netbios_entry() */
  7948. +      name_register_work(d, name, type, nb_flags,0, ipzero, False);
  7949. +    }
  7950. +    else
  7951. +    {
  7952. +      /* a time-to-live allows us to refresh this name with the WINS server. */
  7953. +        queue_netbios_pkt_wins(d,ClientNMB,
  7954. +                 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
  7955. +                 name, type, nb_flags, GET_TTL(0),
  7956. +                 False, True, ipzero, ipzero);
  7957.      }
  7958. +  }
  7959.    else
  7960. -    {
  7961. -      struct in_addr ip;
  7962. -      ip = ipzero;
  7963. -      
  7964. -      queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE,
  7965. -                 name, type, 0,
  7966. -                 False, True, ip);
  7967. -    }
  7968. -}
  7969. -
  7970. -
  7971. -/****************************************************************************
  7972. -  add an entry to the name list
  7973. -  ****************************************************************************/
  7974. -void add_name_entry(char *name,int type,int nb_flags)
  7975. -{
  7976. -  /* always add our own entries */
  7977. -  add_netbios_entry(name,type,nb_flags,0,SELF,ipzero,False);
  7978. -
  7979. -  if (!lp_wins_support())
  7980. -    {
  7981. -      struct in_addr ip;
  7982. -      ip = ipzero;
  7983. -      
  7984. -      queue_netbios_pkt_wins(ClientNMB,NMB_REG,NAME_REGISTER,
  7985. -                 name, type, nb_flags,
  7986. -                 False, True, ip);
  7987. -    }
  7988. +  {
  7989. +    /* broadcast the packet, but it comes from ipzero */
  7990. +      queue_netbios_packet(d,ClientNMB,
  7991. +                 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
  7992. +                 name, type, nb_flags, GET_TTL(0),
  7993. +                 True, True, d->bcast_ip, ipzero);
  7994. +  }
  7995.  }
  7996.  
  7997.  
  7998. @@ -245,815 +171,161 @@
  7999.    **************************************************************************/
  8000.  void add_my_names(void)
  8001.  {
  8002. -  struct in_addr ip;
  8003. +  BOOL wins = lp_wins_support();
  8004. +  struct subnet_record *d;
  8005.  
  8006. -  ip = ipzero;
  8007. -  
  8008. -  add_name_entry(myname,0x20,NB_ACTIVE);
  8009. -  add_name_entry(myname,0x03,NB_ACTIVE);
  8010. -  add_name_entry(myname,0x00,NB_ACTIVE);
  8011. -  add_name_entry(myname,0x1f,NB_ACTIVE);
  8012. -  
  8013. -  add_netbios_entry("*",0x0,NB_ACTIVE,0,SELF,ip,False);
  8014. -  add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False);
  8015. -  add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False);
  8016. -
  8017. -  if (lp_wins_support()) {
  8018. -    /* the 0x1c name gets added by any WINS server it seems */
  8019. -    add_name_entry(my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);      
  8020. -  }
  8021. -}
  8022. -
  8023. -/****************************************************************************
  8024. -  remove all the samba names... from a WINS server if necessary.
  8025. -  **************************************************************************/
  8026. -void remove_my_names()
  8027. -{
  8028. -  struct name_record *n;
  8029. -  
  8030. -  for (n = namelist; n; n = n->next)
  8031. -    {
  8032. -      if (n->source == SELF)
  8033. -    {
  8034. -      /* get all SELF names removed from the WINS server's database */
  8035. -      remove_name_entry(n->name.name, n->name.name_type);
  8036. -    }
  8037. -    }
  8038. -}
  8039. -
  8040. -
  8041. -/*******************************************************************
  8042. -  refresh my own names
  8043. -  ******************************************************************/
  8044. -void refresh_my_names(time_t t)
  8045. -{
  8046. -  static time_t lasttime = 0;
  8047. +  struct in_addr ip = ipzero;
  8048.  
  8049. -  if (t - lasttime < REFRESH_TIME) 
  8050. -    return;
  8051. -  lasttime = t;
  8052. +  /* each subnet entry, including WINS pseudo-subnet, has SELF names */
  8053.  
  8054. -  add_my_names();
  8055. -}
  8056. +  /* XXXX if there was a transport layer added to samba (ipx/spx etc) then
  8057. +     there would be yet _another_ for-loop, this time on the transport type
  8058. +   */
  8059.  
  8060. -/*******************************************************************
  8061. -  expires old names in the namelist
  8062. -  ******************************************************************/
  8063. -void expire_names(time_t t)
  8064. -{
  8065. -  struct name_record *n;
  8066. -  struct name_record *next;
  8067. -  
  8068. -  /* expire old names */
  8069. -  for (n = namelist; n; n = next)
  8070. -    {
  8071. -      if (n->death_time && n->death_time < t)
  8072. -    {
  8073. -      DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
  8074. -      
  8075. -      next = n->next;
  8076. -      
  8077. -      if (n->prev) n->prev->next = n->next;
  8078. -      if (n->next) n->next->prev = n->prev;
  8079. -      
  8080. -      if (namelist == n) namelist = n->next; 
  8081. -      
  8082. -      free(n);
  8083. -    }
  8084. -      else
  8085. -    {
  8086. -      next = n->next;
  8087. -    }
  8088. -    }
  8089. -}
  8090. -
  8091. -
  8092. -/****************************************************************************
  8093. -  response for a reg release received
  8094. -  **************************************************************************/
  8095. -void response_name_release(struct packet_struct *p)
  8096. -{
  8097. -  struct nmb_packet *nmb = &p->packet.nmb;
  8098. -  char *name = nmb->question.question_name.name;
  8099. -  int   type = nmb->question.question_name.name_type;
  8100. -  
  8101. -  DEBUG(4,("response name release received\n"));
  8102. -  
  8103. -  if (nmb->header.rcode == 0 && nmb->answers->rdata)
  8104. -    {
  8105. -      struct in_addr found_ip;
  8106. -      putip((char*)&found_ip,&nmb->answers->rdata[2]);
  8107. -      
  8108. -      if (ismyip(found_ip))
  8109. -    {
  8110. -      remove_netbios_name(name,type,SELF,found_ip);
  8111. -    }
  8112. -    }
  8113. -  else
  8114. -    {
  8115. -      DEBUG(1,("name registration for %s rejected!\n",
  8116. -           namestr(&nmb->question.question_name)));
  8117. -    }
  8118. -}
  8119. -
  8120. -
  8121. -/****************************************************************************
  8122. -  reply to a name release
  8123. -  ****************************************************************************/
  8124. -void reply_name_release(struct packet_struct *p)
  8125. -{
  8126. -  struct nmb_packet *nmb = &p->packet.nmb;
  8127. -  struct in_addr ip;
  8128. -  int rcode=0;
  8129. -  int opcode = nmb->header.opcode;  
  8130. -  int nb_flags = nmb->additional->rdata[0];
  8131. -  BOOL bcast = nmb->header.nm_flags.bcast;
  8132. -  struct name_record *n;
  8133. -  char rdata[6];
  8134. -  
  8135. -  putip((char *)&ip,&nmb->additional->rdata[2]);  
  8136. -  
  8137. -  DEBUG(3,("Name release on name %s rcode=%d\n",
  8138. -        namestr(&nmb->question.question_name),rcode));
  8139. -  
  8140. -  n = find_name_search(&nmb->question.question_name, FIND_GLOBAL, ip);
  8141. -  
  8142. -  /* XXXX under what conditions should we reject the removal?? */
  8143. -  if (n && n->nb_flags == nb_flags)
  8144. -    {
  8145. -      /* success = True;
  8146. -     rcode = 6; */
  8147. -      
  8148. -      remove_name(n);
  8149. -      n = NULL;
  8150. -    }
  8151. -  
  8152. -  if (bcast) return;
  8153. -  
  8154. -  rdata[0] = nb_flags;
  8155. -  rdata[1] = 0;
  8156. -  putip(&rdata[2],(char *)&ip);
  8157. -  
  8158. -  /* Send a NAME RELEASE RESPONSE */
  8159. -  reply_netbios_packet(p,nmb->header.name_trn_id,
  8160. -               rcode,opcode,True,
  8161. -               &nmb->question.question_name,
  8162. -               nmb->question.question_type,
  8163. -               nmb->question.question_class,
  8164. -               0,
  8165. -               rdata, 6);
  8166. -}
  8167. +  for (d = subnetlist; d; d = d->next)
  8168. +  {
  8169. +    BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
  8170.  
  8171. +    if (!d->my_interface && !wins_iface) continue;
  8172.  
  8173. -/****************************************************************************
  8174. -  response for a reg request received
  8175. -  **************************************************************************/
  8176. -void response_name_reg(struct packet_struct *p)
  8177. -{
  8178. -  struct nmb_packet *nmb = &p->packet.nmb;
  8179. -  char *name = nmb->question.question_name.name;
  8180. -  int   type = nmb->question.question_name.name_type;
  8181. -  
  8182. -  DEBUG(4,("response name registration received!\n"));
  8183. -  
  8184. -  if (nmb->header.rcode == 0 && nmb->answers->rdata)
  8185. -    {
  8186. -      int nb_flags = nmb->answers->rdata[0];
  8187. -      struct in_addr found_ip;
  8188. -      int ttl = nmb->answers->ttl;
  8189. -      enum name_source source = REGISTER;
  8190. -      
  8191. -      putip((char*)&found_ip,&nmb->answers->rdata[2]);
  8192. -      
  8193. -      if (ismyip(found_ip)) source = SELF;
  8194. -      
  8195. -      add_netbios_entry(name,type,nb_flags,ttl,source,found_ip,True);
  8196. +    add_my_name_entry(d, myname,0x20,NB_ACTIVE);
  8197. +    add_my_name_entry(d, myname,0x03,NB_ACTIVE);
  8198. +    add_my_name_entry(d, myname,0x00,NB_ACTIVE);
  8199. +    add_my_name_entry(d, myname,0x1f,NB_ACTIVE);
  8200. +
  8201. +    /* these names are added permanently (ttl of zero) and will NOT be
  8202. +       refreshed with the WINS server  */
  8203. +    add_netbios_entry(d,"*",0x0,NB_ACTIVE,0,SELF,ip,False,wins);
  8204. +    add_netbios_entry(d,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins);
  8205. +    add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
  8206. +
  8207. +    if (!wins_iface && lp_domain_logons() && lp_domain_master()) {
  8208. +    /* XXXX the 0x1c is apparently something to do with domain logons */
  8209. +      add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
  8210.      }
  8211. -  else
  8212. +  }
  8213. +  if (lp_domain_master() && (d = find_subnet(ipgrp)))
  8214. +  {
  8215. +    struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
  8216. +    if (work && work->state == MST_NONE)
  8217.      {
  8218. -      DEBUG(1,("name registration for %s rejected!\n",
  8219. -           namestr(&nmb->question.question_name)));
  8220. +      work->state = MST_DOMAIN_NONE;
  8221. +      become_master(d, work);
  8222.      }
  8223. +  }
  8224.  }
  8225.  
  8226.  
  8227.  /****************************************************************************
  8228. -  reply to a reg request
  8229. +  remove all the samba names... from a WINS server if necessary.
  8230.    **************************************************************************/
  8231. -void reply_name_reg(struct packet_struct *p)
  8232. +void remove_my_names()
  8233.  {
  8234. -  struct nmb_packet *nmb = &p->packet.nmb;
  8235. -  struct nmb_name *question = &nmb->question.question_name;
  8236. -  
  8237. -  struct nmb_name *reply_name = question;
  8238. -  char *qname = question->name;
  8239. -  int name_type  = question->name_type;
  8240. -  int name_class = nmb->question.question_class;
  8241. -  
  8242. -  BOOL bcast = nmb->header.nm_flags.bcast;
  8243. -  
  8244. -  int ttl = GET_TTL(nmb->additional->ttl);
  8245. -  int nb_flags = nmb->additional->rdata[0];
  8246. -  BOOL group = NAME_GROUP(nb_flags);
  8247. -  int rcode = 0;  
  8248. -  int opcode = nmb->header.opcode;  
  8249. -  
  8250. -  struct name_record *n = NULL;
  8251. -  BOOL success = True;
  8252. -  BOOL recurse = True; /* true if samba replies yes/no: false if caller */
  8253. -  /* must challenge the current owner */
  8254. -  char rdata[6];
  8255. -  
  8256. -  struct in_addr ip, from_ip;
  8257. -  
  8258. -  DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
  8259. -       namestr(question),inet_ntoa(ip),rcode));
  8260. -  
  8261. -  putip((char *)&from_ip,&nmb->additional->rdata[2]);
  8262. -  ip = from_ip;
  8263. -  
  8264. -  if (group)
  8265. -    {
  8266. -      /* apparently we should return 255.255.255.255 for group queries
  8267. -     (email from MS) */
  8268. -      ip = ipgrp;
  8269. -    }
  8270. -  
  8271. -  /* see if the name already exists */
  8272. -  n = find_name_search(question, FIND_GLOBAL, from_ip);
  8273. -  
  8274. -  if (n)
  8275. -    {
  8276. -      if (!group) /* unique names */
  8277. -    {
  8278. -      if (n->source == SELF || NAME_GROUP(n->nb_flags))
  8279. -        {
  8280. -          /* no-one can register one of samba's names, nor can they
  8281. -         register a name that's a group name as a unique name */
  8282. -          
  8283. -          rcode = 6;
  8284. -          success = False;
  8285. -        }
  8286. -      else if(!ip_equal(ip, n->ip))
  8287. -        {
  8288. -          /* hm. this unique name doesn't belong to them. */
  8289. -          
  8290. -          /* XXXX rfc1001.txt says:
  8291. -           * if we are doing secured WINS, we must send a Wait-Acknowledge
  8292. -           * packet (WACK) to the person who wants the name, then do a
  8293. -           * name query on the person who currently owns the unique name.
  8294. -           * if the current owner is alive, the person who wants the name
  8295. -           * can't have it. if they are not alive, they can.
  8296. -           *
  8297. -           * if we are doing non-secure WINS (which is much simpler) then
  8298. -           * we send a message to the person wanting the name saying 'he
  8299. -           * owns this name: i don't want to hear from you ever again
  8300. -           * until you've checked with him if you can have it!'. we then
  8301. -           * abandon the registration. once the person wanting the name
  8302. -           * has checked with the current owner, they will repeat the
  8303. -           * registration packet if the current owner is dead or doesn't
  8304. -           * want the name.
  8305. -           */
  8306. -          
  8307. -          /* non-secured WINS implementation: caller is responsible
  8308. -         for checking with current owner of name, then getting back
  8309. -         to us... IF current owner no longer owns the unique name */
  8310. -          
  8311. -          rcode = 0;
  8312. -          success = False;
  8313. -          recurse = False;
  8314. -          
  8315. -          /* we inform on the current owner to the caller (which is
  8316. -         why it's non-secure */
  8317. -          
  8318. -          reply_name = &n->name;
  8319. -          
  8320. -          /* name_type  = ?;
  8321. -         name_class = ?;
  8322. -         XXXX sorry, guys: i really can't see what name_type
  8323. -         and name_class should be set to according to rfc1001 */
  8324. -        }
  8325. -      else
  8326. -        {
  8327. -          /* XXXX removed code that checked with the owner of a name */
  8328. -          
  8329. -          n->ip = ip;
  8330. -          n->death_time = ttl?p->timestamp+ttl*3:0;
  8331. -          DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip)));
  8332. -        }
  8333. -    }
  8334. -      else
  8335. -    {
  8336. -      /* refresh the name */
  8337. -      if (n->source != SELF)
  8338. -        {
  8339. -          n->death_time = ttl?p->timestamp + ttl*3:0;
  8340. -        }
  8341. -    }
  8342. -    }
  8343. -  else
  8344. -    {
  8345. -      /* add the name to our subnet/name database */
  8346. -      n = add_netbios_entry(qname,name_type,nb_flags,ttl,REGISTER,ip,True);
  8347. -    }
  8348. -  
  8349. -  if (bcast) return;
  8350. -  
  8351. -  if (success)
  8352. -    {
  8353. -      update_from_reg(nmb->question.question_name.name,
  8354. -              nmb->question.question_name.name_type, from_ip);
  8355. -    }
  8356. -  
  8357. -  rdata[0] = nb_flags;
  8358. -  rdata[1] = 0;
  8359. -  putip(&rdata[2],(char *)&ip);
  8360. -  
  8361. -  /* Send a NAME REGISTRATION RESPONSE (pos/neg)
  8362. -     or and END-NODE CHALLENGE REGISTRATION RESPONSE */
  8363. -  reply_netbios_packet(p,nmb->header.name_trn_id,
  8364. -               rcode,opcode,recurse,
  8365. -               reply_name, name_type, name_class,
  8366. -               ttl,
  8367. -               rdata, 6);
  8368. -}
  8369. +    struct subnet_record *d;
  8370.  
  8371. -
  8372. -/****************************************************************************
  8373. -  reply to a name status query
  8374. -  ****************************************************************************/
  8375. -void reply_name_status(struct packet_struct *p)
  8376. -{
  8377. -  struct nmb_packet *nmb = &p->packet.nmb;
  8378. -  char *qname   = nmb->question.question_name.name;
  8379. -  int ques_type = nmb->question.question_name.name_type;
  8380. -  char rdata[MAX_DGRAM_SIZE];
  8381. -  char *countptr, *buf, *bufend;
  8382. -  int names_added;
  8383. -  struct name_record *n;
  8384. -  
  8385. -  DEBUG(3,("Name status for name %s %s\n",
  8386. -        namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
  8387. -  
  8388. -  n = find_name_search(&nmb->question.question_name,FIND_GLOBAL, p->ip);
  8389. -  
  8390. -  if (!n) return;
  8391. -    
  8392. -  /* XXXX hack, we should calculate exactly how many will fit */
  8393. -  bufend = &rdata[MAX_DGRAM_SIZE] - 18;
  8394. -  countptr = buf = rdata;
  8395. -  buf += 1;
  8396. -  
  8397. -  names_added = 0;
  8398. -  
  8399. -  for (n = namelist ; n && buf < bufend; n = n->next) 
  8400. -    {
  8401. -      int name_type = n->name.name_type;
  8402. -      
  8403. -      if (n->source != SELF) continue;
  8404. -      
  8405. -      /* start with first bit of putting info in buffer: the name */
  8406. -      
  8407. -      bzero(buf,18);
  8408. -      sprintf(buf,"%-15.15s",n->name.name);
  8409. -      strupper(buf);
  8410. -      
  8411. -      /* now check if we want to exclude other workgroup names
  8412. -     from the response. if we don't exclude them, windows clients
  8413. -     get confused and will respond with an error for NET VIEW */
  8414. -      
  8415. -      if (name_type >= 0x1b && name_type <= 0x20 && 
  8416. -      ques_type >= 0x1b && ques_type <= 0x20)
  8417. +    for (d = subnetlist; d; d = d->next)
  8418.      {
  8419. -      if (!strequal(qname, n->name.name)) continue;
  8420. -    }
  8421. -      
  8422. -      /* carry on putting name info in buffer */
  8423. -      
  8424. -      buf[15] = name_type;
  8425. -      buf[16]  = n->nb_flags;
  8426. -      
  8427. -      buf += 18;
  8428. -      
  8429. -      names_added++;
  8430. -    }
  8431. -    
  8432. -  SCVAL(countptr,0,names_added);
  8433. -  
  8434. -  /* XXXXXXX we should fill in more fields of the statistics structure */
  8435. -  bzero(buf,64);
  8436. -  {
  8437. -    extern int num_good_sends,num_good_receives;
  8438. -    SIVAL(buf,20,num_good_sends);
  8439. -    SIVAL(buf,24,num_good_receives);
  8440. -  }
  8441. -  
  8442. -  SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
  8443. -  
  8444. -  buf += 64;
  8445. -  
  8446. -  /* Send a POSITIVE NAME STATUS RESPONSE */
  8447. -  reply_netbios_packet(p,nmb->header.name_trn_id,
  8448. -               0,0,True,
  8449. -               &nmb->question.question_name,
  8450. -               nmb->question.question_type,
  8451. -               nmb->question.question_class,
  8452. -               0,
  8453. -               rdata,PTR_DIFF(buf,rdata));
  8454. -}
  8455. +        struct name_record *n, *next;
  8456.  
  8457. +        for (n = d->namelist; n; n = next)
  8458. +        {
  8459. +            next = n->next;
  8460. +            if (n->source == SELF)
  8461. +            {
  8462. +                /* get all SELF names removed from the WINS server's database */
  8463. +                /* XXXX note: problem occurs if this removes the wrong one! */
  8464.  
  8465. -/***************************************************************************
  8466. -  reply to a name query
  8467. -  ****************************************************************************/
  8468. -static struct name_record *search_for_name(struct nmb_name *question,
  8469. -                       struct in_addr ip, int Time, 
  8470. -                       enum name_search search)
  8471. -{
  8472. -  int name_type = question->name_type;
  8473. -  char *qname = question->name;
  8474. -  BOOL dns_type = name_type == 0x20 || name_type == 0;
  8475. -  
  8476. -  struct name_record *n;
  8477. -  
  8478. -  DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
  8479. -  
  8480. -  /* first look up name in cache. use ip as well as name to locate it */
  8481. -  n = find_name_search(question,search,ip);
  8482. -  
  8483. -  /* now try DNS lookup. */
  8484. -  if (!n)
  8485. -    {
  8486. -      struct in_addr dns_ip;
  8487. -      unsigned long a;
  8488. -      
  8489. -      /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
  8490. -      if (!dns_type)
  8491. -    {
  8492. -      DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
  8493. -      return NULL;
  8494. -    }
  8495. -      
  8496. -      /* look it up with DNS */      
  8497. -      a = interpret_addr(qname);
  8498. -      
  8499. -      putip((char *)&dns_ip,(char *)&a);
  8500. -      
  8501. -      if (!a)
  8502. -    {
  8503. -      /* no luck with DNS. We could possibly recurse here XXXX */
  8504. -      /* if this isn't a bcast then we should send a negative reply XXXX */
  8505. -      DEBUG(3,("no recursion\n"));
  8506. -      add_netbios_entry(qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,True);
  8507. -      return NULL;
  8508. +                remove_name_entry(d,n->name.name, n->name.name_type);
  8509. +            }
  8510. +        }
  8511.      }
  8512. -      
  8513. -      /* add it to our cache of names. give it 2 hours in the cache */
  8514. -      n = add_netbios_entry(qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip,True);
  8515. -      
  8516. -      /* failed to add it? yikes! */
  8517. -      if (!n) return NULL;
  8518. -    }
  8519. -  
  8520. -  /* is our entry already dead? */
  8521. -  if (n->death_time)
  8522. -    {
  8523. -      if (n->death_time < Time) return False;
  8524. -    }
  8525. -  
  8526. -  /* it may have been an earlier failure */
  8527. -  if (n->source == DNSFAIL)
  8528. -    {
  8529. -      DEBUG(3,("DNSFAIL\n"));
  8530. -      return NULL;
  8531. -    }
  8532. -  
  8533. -  DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));      
  8534. -  
  8535. -  return n;
  8536.  }
  8537.  
  8538.  
  8539. -
  8540. -/***************************************************************************
  8541. -  reply to a name query
  8542. -  ****************************************************************************/
  8543. -void reply_name_query(struct packet_struct *p)
  8544. +/*******************************************************************
  8545. +  refresh my own names
  8546. +  ******************************************************************/
  8547. +void refresh_my_names(time_t t)
  8548.  {
  8549. -  struct nmb_packet *nmb = &p->packet.nmb;
  8550. -  struct nmb_name *question = &nmb->question.question_name;
  8551. -  int name_type = question->name_type;
  8552. -  BOOL dns_type = name_type == 0x20 || name_type == 0; 
  8553. -  BOOL bcast = nmb->header.nm_flags.bcast;
  8554. -  int ttl=0;
  8555. -  int rcode = 0;
  8556. -  int nb_flags = 0;
  8557. -  struct in_addr retip;
  8558. -  char rdata[6];
  8559. -  BOOL success = True;
  8560. -  struct name_record *n;
  8561. -  enum name_search search = (dns_type || name_type == 0x1b) ?
  8562. -    FIND_GLOBAL : FIND_SELF;
  8563. +  struct subnet_record *d;
  8564.  
  8565. -  DEBUG(3,("Name query "));
  8566. -  
  8567. -  if ((n = search_for_name(question,p->ip,p->timestamp, search)))
  8568. -    {
  8569. -      /* don't respond to broadcast queries unless the query is for
  8570. -     a name we own or it is for a Primary Domain Controller name */
  8571. -      if (bcast && n->source != SELF && name_type != 0x1b)
  8572. -    {
  8573. -      if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) {
  8574. -        /* never reply with a negative response to broadcast queries */
  8575. -        return;
  8576. -      }
  8577. -    }
  8578. -
  8579. -      /* name is directed query, or it's self, or it's a PDC type name */
  8580. -      ttl = n->death_time - p->timestamp;
  8581. -      retip = n->ip;
  8582. -      nb_flags = n->nb_flags;
  8583. -    }
  8584. -  else
  8585. -    {
  8586. -      if (bcast) return; /* never reply negative response to bcasts */
  8587. -      success = False;
  8588. -    }
  8589. -
  8590. -  /* if the IP is 0 then substitute my IP */
  8591. -  if (zero_ip(retip)) retip = *iface_ip(p->ip);
  8592. -  
  8593. -  if (success)
  8594. -    {
  8595. -      rcode = 0;
  8596. -      DEBUG(3,("OK %s\n",inet_ntoa(retip)));      
  8597. -    }
  8598. -  else
  8599. -    {
  8600. -      rcode = 3;
  8601. -      DEBUG(3,("UNKNOWN\n"));      
  8602. -    }
  8603. -  
  8604. -  if (success)
  8605. +  for (d = subnetlist; d; d = d->next)
  8606. +  {
  8607. +    struct name_record *n;
  8608. +      
  8609. +    for (n = d->namelist; n; n = n->next)
  8610.      {
  8611. -      rdata[0] = nb_flags;
  8612. -      rdata[1] = 0;
  8613. -      putip(&rdata[2],(char *)&retip);
  8614. +      /* each SELF name has an individual time to be refreshed */
  8615. +      if (n->source == SELF && n->refresh_time < time(NULL) && 
  8616. +          n->death_time != 0)
  8617. +      {
  8618. +        add_my_name_entry(d,n->name.name,n->name.name_type,n->nb_flags);
  8619. +      }
  8620.      }
  8621. -  
  8622. -  reply_netbios_packet(p,nmb->header.name_trn_id,
  8623. -               rcode,0,True,
  8624. -               &nmb->question.question_name,
  8625. -               nmb->question.question_type,
  8626. -               nmb->question.question_class,
  8627. -               ttl,
  8628. -               rdata, success ? 6 : 0);
  8629. +  }
  8630.  }
  8631.  
  8632.  
  8633. +/*******************************************************************
  8634. +  queries names occasionally. an over-cautious, non-trusting WINS server!
  8635.  
  8636. -/****************************************************************************
  8637. -response from a name query
  8638. -****************************************************************************/
  8639. -static void response_netbios_packet(struct packet_struct *p)
  8640. +  this function has been added because nmbd could be restarted. it
  8641. +  is generally a good idea to check all the names that have been
  8642. +  reloaded from file.
  8643. +
  8644. +  XXXX which names to poll and which not can be refined at a later date.
  8645. +  ******************************************************************/
  8646. +void query_refresh_names(void)
  8647.  {
  8648. -  struct nmb_packet *nmb = &p->packet.nmb;
  8649. -  struct nmb_name *question = &nmb->question.question_name;
  8650. -  char *qname = question->name;
  8651. -  BOOL bcast = nmb->header.nm_flags.bcast;
  8652. -  struct name_response_record *n;
  8653. +    struct name_record *n;
  8654. +    struct subnet_record *d = find_subnet(ipgrp);
  8655.  
  8656. -  if (nmb->answers == NULL)
  8657. -    {
  8658. -      DEBUG(3,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
  8659. -           inet_ntoa(p->ip),
  8660. -           BOOLSTR(bcast)));
  8661. -      return;
  8662. -    }
  8663. -  
  8664. -  if (nmb->answers->rr_type == NMB_STATUS) {
  8665. -    DEBUG(3,("Name status "));
  8666. -  }
  8667. +    static time_t lasttime = 0;
  8668. +    time_t t = time(NULL);
  8669.  
  8670. -  if (nmb->answers->rr_type == NMB_QUERY)    {
  8671. -    DEBUG(3,("Name query "));
  8672. -  }
  8673. +    int count = 0;
  8674. +    int name_refresh_time = NAME_POLL_REFRESH_TIME;
  8675. +    int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
  8676. +    if (max_count > 10) max_count = 10;
  8677.  
  8678. -  if (nmb->answers->rr_type == NMB_REG) {
  8679. -    DEBUG(3,("Name registration "));
  8680. -  }
  8681. +    name_refresh_time = NAME_POLL_INTERVAL * max_count / 2;
  8682.  
  8683. -  if (nmb->answers->rr_type == NMB_REL) {
  8684. -    DEBUG(3,("Name release "));
  8685. -  }
  8686. +    /* if (!lp_poll_wins()) return; polling of registered names allowed */
  8687.  
  8688. -  DEBUG(3,("response for %s from %s (bcast=%s)\n",
  8689. -       namestr(&nmb->answers->rr_name),
  8690. -       inet_ntoa(p->ip),
  8691. -       BOOLSTR(bcast)));
  8692. -  
  8693. -  if (!(n = find_name_query(nmb->header.name_trn_id))) {
  8694. -    DEBUG(3,("unknown response (received too late or from nmblookup?)\n"));
  8695. -    return;
  8696. -  }
  8697. +    if (!d) return;
  8698.  
  8699. -  n->num_msgs++; /* count number of responses received */
  8700. +    if (!lasttime) lasttime = t;
  8701. +    if (t - lasttime < NAME_POLL_INTERVAL) return;
  8702.  
  8703. -  switch (n->cmd_type)
  8704. -    {
  8705. -    case MASTER_SERVER_CHECK     : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
  8706. -    case SERVER_CHECK            : DEBUG(4,("SERVER_CHECK\n")); break;
  8707. -    case FIND_MASTER             : DEBUG(4,("FIND_MASTER\n")); break;
  8708. -    case NAME_STATUS_MASTER_CHECK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
  8709. -    case NAME_STATUS_CHECK       : DEBUG(4,("NAME_STATUS_CHECK\n")); break;
  8710. -    case CHECK_MASTER            : DEBUG(4,("CHECK_MASTER\n")); break;
  8711. -    case NAME_CONFIRM_QUERY      : DEBUG(4,("NAME_CONFIRM_QUERY\n")); break;
  8712. -    default: break;
  8713. -    }
  8714. -  switch (n->cmd_type)
  8715. -    {
  8716. -    case MASTER_SERVER_CHECK:
  8717. -    case SERVER_CHECK:
  8718. -    case FIND_MASTER:
  8719. -      {
  8720. -    if (nmb->answers->rr_type == NMB_QUERY)
  8721. -      {
  8722. -        enum cmd_type cmd = (n->cmd_type == MASTER_SERVER_CHECK) ?
  8723. -          NAME_STATUS_MASTER_CHECK :
  8724. -          NAME_STATUS_CHECK;
  8725. -        if (n->num_msgs > 1 && !strequal(qname,n->name.name))
  8726. -          {
  8727. -        /* one subnet, one master browser per workgroup */
  8728. -        /* XXXX force an election? */
  8729. -        DEBUG(1,("more than one master browser replied!\n"));
  8730. -          }
  8731. -        
  8732. -        /* initiate a name status check on the server that replied */
  8733. -        queue_netbios_packet(ClientNMB,NMB_STATUS, cmd,
  8734. -                 nmb->answers->rr_name.name,
  8735. -                 nmb->answers->rr_name.name_type,0,
  8736. -                 False,False,n->to_ip);
  8737. -      }
  8738. -    else
  8739. -      {
  8740. -        DEBUG(1,("Name query reply has wrong answer rr_type\n"));
  8741. -      }
  8742. -    break;
  8743. -      }
  8744. -      
  8745. -    case NAME_STATUS_MASTER_CHECK:
  8746. -    case NAME_STATUS_CHECK:
  8747. -      {
  8748. -    if (nmb->answers->rr_type == NMB_STATUS)
  8749. -      {
  8750. -        /* NMB_STATUS arrives: contains the workgroup name 
  8751. -           and server name we require */
  8752. -        struct nmb_name name;
  8753. -        fstring serv_name;
  8754. -        
  8755. -        if (interpret_node_status(nmb->answers->rdata,
  8756. -                      &name,0x1d,serv_name,p->ip))
  8757. -          {
  8758. -        if (*serv_name)
  8759. -          {
  8760. -            sync_server(n->cmd_type,serv_name,
  8761. -                name.name,name.name_type,
  8762. -                n->to_ip);
  8763. -          }
  8764. -          }
  8765. -        else
  8766. -          {
  8767. -        DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
  8768. -          }
  8769. -      }
  8770. -    else
  8771. -      {
  8772. -        DEBUG(1,("Name status reply has wrong answer rr_type\n"));
  8773. -      }
  8774. -    break;
  8775. -      }
  8776. -      
  8777. -    case CHECK_MASTER:
  8778. -      {
  8779. -    /* no action required here. it's when NO responses are received
  8780. -       that we need to do something (see expire_name_query_entries) */
  8781. -    
  8782. -    DEBUG(4, ("Master browser exists for %s at %s\n",
  8783. -          namestr(&n->name),
  8784. -          inet_ntoa(n->to_ip)));
  8785. -    if (n->num_msgs > 1)
  8786. -      {
  8787. -        DEBUG(1,("more than one master browser!\n"));
  8788. -      }
  8789. -    if (nmb->answers->rr_type != NMB_QUERY)
  8790. -      {
  8791. -        DEBUG(1,("Name query reply has wrong answer rr_type\n"));
  8792. -      }
  8793. -    break;
  8794. -      }
  8795. -    case NAME_CONFIRM_QUERY:
  8796. -      {
  8797. -    DEBUG(4, ("Name query at WINS server: %s at %s - ",
  8798. -          namestr(&n->name),
  8799. -          inet_ntoa(n->to_ip)));
  8800. -    if (nmb->header.rcode == 0 && nmb->answers->rdata)
  8801. -      {
  8802. -        int nb_flags = nmb->answers->rdata[0];
  8803. -        struct in_addr found_ip;
  8804. -        putip((char*)&found_ip,&nmb->answers->rdata[2]);
  8805. -        
  8806. -        DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
  8807. -        add_netbios_entry(nmb->answers->rr_name.name,
  8808. -                  nmb->answers->rr_name.name_type,
  8809. -                  nb_flags,GET_TTL(0),STATUS_QUERY,found_ip,False);
  8810. -      }
  8811. -    else
  8812. -      {
  8813. -        DEBUG(4, (" NEGATIVE RESPONSE\n"));
  8814. -      }
  8815. -    
  8816. -    break;
  8817. -      }
  8818. -    default:
  8819. -      {
  8820. -    DEBUG(0,("unknown command received in response_netbios_packet\n"));
  8821. -    break;
  8822. -      }
  8823. -    }
  8824. -}
  8825. +    lasttime = time(NULL);
  8826.  
  8827. +    for (n = d->namelist; n; n = n->next)
  8828. +    {
  8829. +        /* only do unique, registered names */
  8830.  
  8831. -/****************************************************************************
  8832. -  process a nmb packet
  8833. -  ****************************************************************************/
  8834. -void process_nmb(struct packet_struct *p)
  8835. -{
  8836. -  struct nmb_packet *nmb = &p->packet.nmb;
  8837. -
  8838. -  debug_nmb_packet(p);
  8839. +        if (n->source != REGISTER) continue;
  8840. +        if (!NAME_GROUP(n->nb_flags)) continue;
  8841.  
  8842. -  switch (nmb->header.opcode) 
  8843. -    {
  8844. -    case 5:
  8845. -    case 8:
  8846. -    case 9:
  8847. -      {
  8848. -    if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
  8849. -    if (nmb->header.response)
  8850. -      response_name_reg(p);
  8851. -    else
  8852. -      reply_name_reg(p);
  8853. -    break;
  8854. -      }
  8855. -      
  8856. -    case 0:
  8857. -      {
  8858. -    if (nmb->header.response)
  8859. -      {
  8860. -        switch (nmb->question.question_type)
  8861. -          {
  8862. -          case 0x0:
  8863. +        if (n->refresh_time < t)
  8864.          {
  8865. -          response_netbios_packet(p);
  8866. -          break;
  8867. +          DEBUG(3,("Polling name %s\n", namestr(&n->name)));
  8868. +          
  8869. +          queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
  8870. +                n->name.name, n->name.name_type,
  8871. +                0,0,
  8872. +                False,False,n->ip,n->ip);
  8873. +          count++;
  8874.          }
  8875. -          }
  8876. -        return;
  8877. -      }
  8878. -    else if (nmb->header.qdcount>0) 
  8879. -      {
  8880. -        switch (nmb->question.question_type)
  8881. -          {
  8882. -          case NMB_QUERY:
  8883. -        {
  8884. -          reply_name_query(p);
  8885. -          break;
  8886. -        }
  8887. -          case NMB_STATUS:
  8888. +
  8889. +        if (count >= max_count)
  8890.          {
  8891. -          reply_name_status(p);
  8892. -          break;
  8893. +            /* don't do too many of these at once, but do enough to
  8894. +               cover everyone in the list */
  8895. +            return;
  8896.          }
  8897. -          }
  8898. -        return;
  8899. -      }
  8900. -    break;
  8901. -      }
  8902. -      
  8903. -    case 6:
  8904. -      {
  8905. -    if (nmb->header.qdcount==0 || nmb->header.arcount==0)
  8906. -      {
  8907. -        DEBUG(2,("netbios release packet rejected\n"));
  8908. -        break;
  8909. -      }
  8910. -    
  8911. -    if (nmb->header.response)
  8912. -      response_name_release(p);
  8913. -    else
  8914. -      reply_name_release(p);
  8915. -    break;
  8916. -      }
  8917. -    }
  8918. +
  8919. +        /* this name will be checked on again, if it's not removed */
  8920. +        n->refresh_time += name_refresh_time;
  8921. +    }
  8922.  }
  8923.  
  8924. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameserv.doc samba-1.9.16alpha11/source/nameserv.doc
  8925. --- samba-1.9.16alpha10/source/nameserv.doc    Thu Jan  1 10:00:00 1970
  8926. +++ samba-1.9.16alpha11/source/nameserv.doc    Thu Jul 11 04:48:28 1996
  8927. @@ -0,0 +1,132 @@
  8928. +this module deals with general maintenance of NetBIOS names.
  8929. +
  8930. +/*************************************************************************
  8931. +  query_refresh_names()
  8932. +  *************************************************************************/
  8933. +
  8934. +this function is responsible for polling all names registered in the
  8935. +WINS database. it is planned to enable this function should samba
  8936. +detect an inconsistency on the network, which could occur if the
  8937. +samba NetBIOS daemon dies and is restarted.
  8938. +
  8939. +polling is done very infrequently, but all names will be covered
  8940. +within a period NAME_POLL_REFRESH_TIME. a group of at most ten names
  8941. +will be queried at once, at intervals of NAME_POLL_INTERVAL seconds.
  8942. +if the total number of names queried in this way will take too long,
  8943. +then the time that an individual name will next be polled is
  8944. +increased accordingly.
  8945. +
  8946. +name query polling is functionality over-and-above the normal
  8947. +requirement (see rfc1001.txt 15.1.7 point 7). it is normally the
  8948. +responsibility of the owner of a name to re-register the name at
  8949. +regular intervals.
  8950. +
  8951. +
  8952. +/*************************************************************************
  8953. +  refresh_my_names()
  8954. +  *************************************************************************/
  8955. +
  8956. +this function is responsible for refreshing samba's names that have
  8957. +been registered with other servers on a local subnet, or with another
  8958. +WINS server if samba is using one.
  8959. +
  8960. +samba's names' refresh_time will be updated through the use of the function
  8961. +add_my_name_entry().
  8962. +
  8963. +
  8964. +/*************************************************************************
  8965. +  remove_my_names()
  8966. +  *************************************************************************/
  8967. +
  8968. +this function is responsible for removing all samba's SELF names. it
  8969. +is used when samba receives a SIG_TERM. samba at present does not wait
  8970. +for the WINS server to reply to the name releases sent out.
  8971. +
  8972. +
  8973. +/*************************************************************************
  8974. +  add_my_names()
  8975. +  *************************************************************************/
  8976. +
  8977. +this function is responsible for adding and registering if necessary all
  8978. +samba's SELF names, on each of its local subnets and with another WINS
  8979. +server if samba is using one.
  8980. +
  8981. +/*************************************************************************
  8982. +  add_my_name_entry()
  8983. +  *************************************************************************/
  8984. +
  8985. +this function is responsible for registering or re-registering one of
  8986. +samba's names, either on the local subnet or with another WINS server
  8987. +if samba is using one.
  8988. +
  8989. +if the name is already in samba's database, then it is re-registered,
  8990. +otherwise it is simply registered.
  8991. +
  8992. +if the name is being registered in a WINS capacity (the subnet to which
  8993. +the name should be added is the WINS pseudo-subnet) then we add the entry
  8994. +immediately if samba is a WINS server. it uses name_register_work()
  8995. +because if the name is being added as part of becoming a master browser,
  8996. +we want to carry on that process. if the name is registered with another
  8997. +WINS server, we must wait for an answer from that WINS server. either
  8998. +name_register_work() or name_unregister_work() will be called as a result.
  8999. +
  9000. +if the name is being registered on a local subnet, then it is
  9001. +broadcast. an explicit rejection from another host will result
  9002. +in name_unregister_work() being called. no response will, after
  9003. +retrying, result in name_register_work() being called.
  9004. +
  9005. +what ever method is used, the name will either be registered
  9006. +or rejected, and what ever process was taking place (becoming
  9007. +a master browser for example) will carry on.
  9008. +
  9009. +expire_netbios_response_entries() is responsible for taking further
  9010. +action if no response to the registration is received. 
  9011. +
  9012. +note that there may be a large number of function calls on the
  9013. +stack if become_master() is called and samba is configured as
  9014. +a WINS server. the loop will be:
  9015. +
  9016. +become_master(), add_my_name_entry(), name_register_work() and
  9017. +back to become_master() with the new value of the workgroup
  9018. +'state'.
  9019. +
  9020. +
  9021. +/*************************************************************************
  9022. +  remove_name_entry()
  9023. +  *************************************************************************/
  9024. +
  9025. +this function is responsible for removing a NetBIOS name. if the name
  9026. +being removed is registered on a local subnet, a name release should be
  9027. +broadcast on the local subnet.
  9028. +
  9029. +if the name is being released in a WINS capacity (the subnet to
  9030. +which the name should be added is the WINS pseudo-subnet) then we
  9031. +remove the entry immediately if samba is a WINS server. it uses
  9032. +name_unregister_work() because if the name is being added as part of
  9033. +becoming a master browser, we want to terminate that process. if the
  9034. +name is released from another WINS server, we must wait for an
  9035. +answer from that WINS server. name_unregister_work() will 
  9036. +definitely be called as a result, because at present we ignore
  9037. +negative responses for a name release from a WINS server.
  9038. +
  9039. +if the name is being releasedd on a local subnet, then it is
  9040. +broadcast. name_unregister_work() will definitely be called
  9041. +because we ignore negative name releases at present.
  9042. +
  9043. +what ever method is used, the name will be released. (NOT TRUE!
  9044. +see response_name_release())
  9045. +
  9046. +expire_netbios_response_entries() is responsible for taking further action
  9047. +if no response to the name release is received.
  9048. +
  9049. +
  9050. +/*************************************************************************
  9051. +  load_netbios_names()
  9052. +  *************************************************************************/
  9053. +
  9054. +this function is responsible for loading any NetBIOS names that samba,
  9055. +in its WINS capacity, has written out to disk. all the relevant details
  9056. +are recorded in this file, including the time-to-live. should the 
  9057. +time left to live be small, the name is not added back in to samba's
  9058. +WINS database.
  9059. +
  9060. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameserv.h samba-1.9.16alpha11/source/nameserv.h
  9061. --- samba-1.9.16alpha10/source/nameserv.h    Mon Jun 10 15:18:56 1996
  9062. +++ samba-1.9.16alpha11/source/nameserv.h    Thu Jul 18 20:53:15 1996
  9063. @@ -20,18 +20,29 @@
  9064.     
  9065.  */
  9066.  
  9067. +#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
  9068. +
  9069.  /* NTAS uses 2, NT uses 1, WfWg uses 0 */
  9070.  #define MAINTAIN_LIST    2
  9071.  #define ELECTION_VERSION 1
  9072.  
  9073. -#define MAX_DGRAM_SIZE (80*18+64)
  9074. +#define MAX_DGRAM_SIZE (576) /* tcp/ip datagram limit is 576 bytes */
  9075.  #define MIN_DGRAM_SIZE 12
  9076.  
  9077.  #define NMB_QUERY  0x20
  9078.  #define NMB_STATUS 0x21
  9079. -#define NMB_REG    0x05
  9080. -#define NMB_REL    0x06
  9081.  
  9082. +#define NMB_REG         0x05 /* see rfc1002.txt 4.2.2,3,5,6,7,8 */
  9083. +#define NMB_REG_REFRESH 0x09 /* see rfc1002.txt 4.2.4 */
  9084. +#define NMB_REL         0x06 /* see rfc1002.txt 4.2.9,10,11 */
  9085. +#define NMB_WAIT_ACK    0x07 /* see rfc1002.txt 4.2.16 */
  9086. +/* XXXX what about all the other types?? 0x1, 0x2, 0x3, 0x4, 0x8? */
  9087. +
  9088. +#define FIND_SELF  0x01
  9089. +#define FIND_WINS  0x02
  9090. +#define FIND_LOCAL 0x04
  9091. +
  9092. +/* NetBIOS flags */
  9093.  #define NB_GROUP  0x80
  9094.  #define NB_PERM   0x02
  9095.  #define NB_ACTIVE 0x04
  9096. @@ -44,7 +55,10 @@
  9097.  #define NB_FLGMSK 0x60
  9098.  
  9099.  #define REFRESH_TIME (15*60)
  9100. +#define NAME_POLL_REFRESH_TIME (5*60)
  9101. +#define NAME_POLL_INTERVAL 15
  9102.  
  9103. +/* NetBIOS flag identifier */
  9104.  #define NAME_PERMANENT(p) ((p) & NB_PERM)
  9105.  #define NAME_ACTIVE(p)    ((p) & NB_ACTIVE)
  9106.  #define NAME_CONFLICT(p)  ((p) & NB_CONFL)
  9107. @@ -56,23 +70,46 @@
  9108.  #define NAME_MFLAG(p)     (((p) & NB_FLGMSK) == NB_MFLAG)
  9109.  #define NAME__FLAG(p)     (((p) & NB_FLGMSK) == NB__FLAG)
  9110.  
  9111. +/* server type identifiers */
  9112. +#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
  9113. +#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
  9114. +#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL)
  9115. +
  9116. +/* microsoft browser NetBIOS name */
  9117.  #define MSBROWSE "\001\002__MSBROWSE__\002"
  9118.  
  9119. -enum name_search { FIND_SELF, FIND_GLOBAL };
  9120. +/* mail slots */
  9121. +#define BROWSE_MAILSLOT    "\\MAILSLOT\\BROWSE"
  9122. +#define NET_LOGON_MAILSLOT "\\MAILSLOT\\NET\\NETLOGON"
  9123. +
  9124.  enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
  9125.  enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
  9126.  enum packet_type {NMB_PACKET, DGRAM_PACKET};
  9127. -enum cmd_type
  9128. +enum master_state
  9129.  {
  9130. -    NAME_STATUS_MASTER_CHECK,
  9131. -    NAME_STATUS_CHECK,
  9132. -    MASTER_SERVER_CHECK,
  9133. -    SERVER_CHECK,
  9134. -    FIND_MASTER,
  9135. -    CHECK_MASTER,
  9136. +   MST_NONE,
  9137. +   MST_WON,
  9138. +   MST_MSB,
  9139. +   MST_BROWSER,
  9140. +   MST_DOMAIN_NONE,
  9141. +   MST_DOMAIN_MEM,
  9142. +   MST_DOMAIN_TST,
  9143. +   MST_DOMAIN
  9144. +};
  9145. +
  9146. +enum state_type
  9147. +{
  9148. +    NAME_STATUS_PDC_SRV_CHK,
  9149. +    NAME_STATUS_SRV_CHK,
  9150. +    NAME_REGISTER_CHALLENGE,
  9151.      NAME_REGISTER,
  9152.      NAME_RELEASE,
  9153. -    NAME_CONFIRM_QUERY
  9154. +    NAME_QUERY_CONFIRM,
  9155. +    NAME_QUERY_SYNC,
  9156. +    NAME_QUERY_PDC_SRV_CHK,
  9157. +    NAME_QUERY_SRV_CHK,
  9158. +    NAME_QUERY_FIND_MST,
  9159. +    NAME_QUERY_MST_CHK
  9160.  };
  9161.  
  9162.  /* a netbios name structure */
  9163. @@ -87,11 +124,15 @@
  9164.  {
  9165.    struct name_record *next;
  9166.    struct name_record *prev;
  9167. -  struct nmb_name name;
  9168. -  time_t death_time;
  9169. -  struct in_addr ip;
  9170. -  int nb_flags;
  9171. -  enum name_source source;
  9172. +
  9173. +  struct nmb_name name;    /* the netbios name */
  9174. +  struct in_addr ip;       /* ip address of host that owns this name */
  9175. +  int nb_flags;            /* netbios flags */
  9176. +
  9177. +  enum name_source source; /* where the name came from */
  9178. +
  9179. +  time_t death_time; /* time record must be removed (do not remove if 0) */
  9180. +  time_t refresh_time; /* time record should be refreshed */
  9181.  };
  9182.  
  9183.  /* browse and backup server cache for synchronising browse list */
  9184. @@ -127,6 +168,9 @@
  9185.  
  9186.    struct server_record *serverlist;
  9187.  
  9188. +  /* stage of development from non-master to master browser / domain master */
  9189. +  enum master_state state;
  9190. +
  9191.    /* work group info */
  9192.    fstring work_group;
  9193.    int     token;        /* used when communicating with backup browsers */
  9194. @@ -137,6 +181,7 @@
  9195.    int announce_interval;
  9196.    BOOL    needannounce;
  9197.  
  9198. +
  9199.    /* election info */
  9200.    BOOL    RunningElection;
  9201.    BOOL    needelection;
  9202. @@ -144,13 +189,64 @@
  9203.    uint32  ElectionCriterion;
  9204.  };
  9205.  
  9206. -/* a subnet structure. it contains a list of workgroups */
  9207. +/* initiated name queries recorded in this list to track any responses... */
  9208. +struct response_record
  9209. +{
  9210. +  struct response_record *next;
  9211. +  struct response_record *prev;
  9212. +
  9213. +  uint16 response_id;
  9214. +  enum state_type state;
  9215. +
  9216. +  int fd;
  9217. +  int quest_type;
  9218. +  struct nmb_name name;
  9219. +  int nb_flags;
  9220. +  time_t ttl;
  9221. +
  9222. +  BOOL bcast;
  9223. +  BOOL recurse;
  9224. +  struct in_addr send_ip;
  9225. +  struct in_addr reply_to_ip;
  9226. +
  9227. +  int num_msgs;
  9228. +
  9229. +  time_t repeat_time;
  9230. +  time_t repeat_interval;
  9231. +  int    repeat_count;
  9232. +};
  9233. +
  9234. +/* a subnet structure. it contains a list of workgroups and netbios names*/
  9235. +
  9236. +/* note that a subnet of 255.255.255.255 contains all the WINS netbios names.
  9237. +   all communication from such nodes are on a non-broadcast basis: they
  9238. +   are point-to-point (P nodes) or mixed point-to-point and broadcast
  9239. +   (M nodes). M nodes use point-to-point as a preference, and will use
  9240. +   broadcasting for certain activities, or will resort to broadcasting as a
  9241. +   last resort, if the WINS server fails (users of wfwg will notice that their
  9242. +   machine often freezes for 30 seconds at a time intermittently, if the WINS
  9243. +   server is down).
  9244. +
  9245. +   B nodes will have their own, totally separate subnet record, with their
  9246. +   own netbios name set. these do NOT interact with other subnet records'
  9247. +   netbios names, INCLUDING the WINS one (with an ip "address", so called,
  9248. +   of 255.255.255.255)
  9249. +
  9250. +   there is a separate response list for each subnet record. in the case of
  9251. +   the 255.255.255.255 subnet record (WINS), the WINS server will be able to
  9252. +   use this to poll (infrequently!) each of its entries, to ensure that the
  9253. +   names are still in use.
  9254. +   XXXX this polling is a planned feature for a really over-cautious WINS server 
  9255. +*/
  9256. +
  9257.  struct subnet_record
  9258.  {
  9259.    struct subnet_record *next;
  9260.    struct subnet_record *prev;
  9261.  
  9262. -  struct work_record *workgrouplist;
  9263. +  struct work_record *workgrouplist; /* list of workgroups */
  9264. +  struct name_record *namelist;      /* list of netbios names */
  9265. +  struct response_record *responselist; /* list of responses expected */
  9266.  
  9267.    struct in_addr bcast_ip;
  9268.    struct in_addr mask_ip;
  9269. @@ -202,25 +298,6 @@
  9270.  };
  9271.  
  9272.  
  9273. -/* initiated name queries recorded in this list to track any responses... */
  9274. -struct name_response_record
  9275. -{
  9276. -  struct name_response_record *next;
  9277. -  struct name_response_record *prev;
  9278. -
  9279. -  uint16 response_id;
  9280. -  enum cmd_type cmd_type;
  9281. -
  9282. -  int fd;
  9283. -  struct nmb_name name;
  9284. -  BOOL bcast;
  9285. -  BOOL recurse;
  9286. -  struct in_addr to_ip;
  9287. -
  9288. -  time_t start_time;
  9289. -  int num_msgs;
  9290. -};
  9291. -
  9292.  /* a datagram - this normally contains SMB data in the data[] array */
  9293.  struct dgram_packet {
  9294.    struct {
  9295. @@ -258,11 +335,6 @@
  9296.      struct dgram_packet dgram;
  9297.    } packet;
  9298.  };
  9299. -
  9300. -
  9301. -#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
  9302. -#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
  9303. -#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL)
  9304.  
  9305.  
  9306.  /* ids for netbios packet types */
  9307. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameservreply.c samba-1.9.16alpha11/source/nameservreply.c
  9308. --- samba-1.9.16alpha10/source/nameservreply.c    Thu Jan  1 10:00:00 1970
  9309. +++ samba-1.9.16alpha11/source/nameservreply.c    Thu Jul 18 20:53:16 1996
  9310. @@ -0,0 +1,552 @@
  9311. +/* 
  9312. +   Unix SMB/Netbios implementation.
  9313. +   Version 1.9.
  9314. +   NBT netbios routines and daemon - version 2
  9315. +   Copyright (C) Andrew Tridgell 1994-1996
  9316. +   
  9317. +   This program is free software; you can redistribute it and/or modify
  9318. +   it under the terms of the GNU General Public License as published by
  9319. +   the Free Software Foundation; either version 2 of the License, or
  9320. +   (at your option) any later version.
  9321. +   
  9322. +   This program is distributed in the hope that it will be useful,
  9323. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  9324. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9325. +   GNU General Public License for more details.
  9326. +   
  9327. +   You should have received a copy of the GNU General Public License
  9328. +   along with this program; if not, write to the Free Software
  9329. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  9330. +   
  9331. +   Module name: nameservreply.c
  9332. +
  9333. +   Revision History:
  9334. +
  9335. +   14 jan 96: lkcl@pires.co.uk
  9336. +   added multiple workgroup domain master support
  9337. +
  9338. +   04 jul 96: lkcl@pires.co.uk
  9339. +   created module nameservreply containing NetBIOS reply functions
  9340. +
  9341. +*/
  9342. +
  9343. +#include "includes.h"
  9344. +
  9345. +extern int ClientNMB;
  9346. +
  9347. +extern int DEBUGLEVEL;
  9348. +
  9349. +extern struct in_addr ipgrp;
  9350. +
  9351. +
  9352. +/****************************************************************************
  9353. +  add a netbios entry. respond to the (possibly new) owner.
  9354. +  **************************************************************************/
  9355. +void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
  9356. +                uint16 response_id,
  9357. +                struct nmb_name *name,
  9358. +                int nb_flags, int ttl, struct in_addr register_ip,
  9359. +                BOOL new_owner, struct in_addr reply_to_ip)
  9360. +{
  9361. +    /* register the old or the new owners' ip */
  9362. +    add_netbios_entry(d,name->name,name->name_type,
  9363. +                        nb_flags,ttl,REGISTER,register_ip,False,True);
  9364. +
  9365. +    /* reply yes or no to the host that requested the name */
  9366. +    send_name_response(fd,from_ip, response_id, NMB_REG,
  9367. +                new_owner, True,
  9368. +                name, nb_flags, ttl, reply_to_ip);
  9369. +}
  9370. +
  9371. +/****************************************************************************
  9372. +send a registration / release response: pos/neg
  9373. +**************************************************************************/
  9374. +void send_name_response(int fd, struct in_addr from_ip,
  9375. +                int name_trn_id, int opcode, BOOL success, BOOL recurse,
  9376. +                struct nmb_name *reply_name, int nb_flags, int ttl,
  9377. +                struct in_addr ip)
  9378. +{
  9379. +  char rdata[6];
  9380. +  struct packet_struct p;
  9381. +
  9382. +  int rcode = 0;  
  9383. +
  9384. +  if (success == False)
  9385. +  {
  9386. +    /* NEGATIVE RESPONSE */
  9387. +    rcode = 6;
  9388. +  }
  9389. +  else if (opcode == NMB_REG && recurse == False)
  9390. +  {
  9391. +    /* END-NODE CHALLENGE REGISTRATION RESPONSE */
  9392. +    rcode = 0;
  9393. +  }
  9394. +  
  9395. +  rdata[0] = nb_flags;
  9396. +  rdata[1] = 0;
  9397. +  putip(&rdata[2],(char *)&ip);
  9398. +  
  9399. +  p.ip = from_ip;
  9400. +  p.port = NMB_PORT;
  9401. +  p.fd = fd;
  9402. +  p.timestamp = time(NULL);
  9403. +  p.packet_type = NMB_PACKET;
  9404. +
  9405. +  reply_netbios_packet(&p,name_trn_id,
  9406. +               rcode,opcode,opcode,recurse,
  9407. +               reply_name, 0x20, 0x1,
  9408. +               ttl, 
  9409. +               rdata, 6);
  9410. +}
  9411. +
  9412. +
  9413. +/****************************************************************************
  9414. +reply to a name release
  9415. +****************************************************************************/
  9416. +void reply_name_release(struct packet_struct *p)
  9417. +{
  9418. +  struct nmb_packet *nmb = &p->packet.nmb;
  9419. +  struct in_addr ip;
  9420. +  int nb_flags = nmb->additional->rdata[0];
  9421. +  BOOL bcast = nmb->header.nm_flags.bcast;
  9422. +  struct name_record *n;
  9423. +  struct subnet_record *d = NULL;
  9424. +  int search = 0;
  9425. +  BOOL success = False;
  9426. +  
  9427. +  putip((char *)&ip,&nmb->additional->rdata[2]);  
  9428. +  
  9429. +  DEBUG(3,("Name release on name %s\n",
  9430. +       namestr(&nmb->question.question_name)));
  9431. +  
  9432. +  if (!(d = find_req_subnet(p->ip, bcast)))
  9433. +  {
  9434. +    DEBUG(3,("response packet: bcast %s not known\n",
  9435. +            inet_ntoa(p->ip)));
  9436. +    return;
  9437. +  }
  9438. +
  9439. +  if (bcast)
  9440. +    search &= FIND_LOCAL;
  9441. +  else
  9442. +    search &= FIND_WINS;
  9443. +
  9444. +  n = find_name_search(&d, &nmb->question.question_name, 
  9445. +                    search, ip);
  9446. +  
  9447. +  /* XXXX under what conditions should we reject the removal?? */
  9448. +  if (n && n->nb_flags == nb_flags)
  9449. +  {
  9450. +      success = True;
  9451. +      
  9452. +      remove_name(d,n);
  9453. +      n = NULL;
  9454. +  }
  9455. +  
  9456. +  if (bcast) return;
  9457. +  
  9458. +  /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
  9459. +  send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REL,
  9460. +                        success, False,
  9461. +                        &nmb->question.question_name, nb_flags, 0, ip);
  9462. +}
  9463. +
  9464. +
  9465. +/****************************************************************************
  9466. +reply to a reg request
  9467. +**************************************************************************/
  9468. +void reply_name_reg(struct packet_struct *p)
  9469. +{
  9470. +  struct nmb_packet *nmb = &p->packet.nmb;
  9471. +  struct nmb_name *question = &nmb->question.question_name;
  9472. +  
  9473. +  struct nmb_name *reply_name = question;
  9474. +
  9475. +  char *qname      = question->name;
  9476. +  int   qname_type = question->name_type;
  9477. +  BOOL bcast = nmb->header.nm_flags.bcast;
  9478. +  
  9479. +  int ttl = GET_TTL(nmb->additional->ttl);
  9480. +  int nb_flags = nmb->additional->rdata[0];
  9481. +  BOOL group = NAME_GROUP(nb_flags);
  9482. +
  9483. +  struct subnet_record *d = NULL;
  9484. +  struct name_record *n = NULL;
  9485. +
  9486. +  BOOL success = True;
  9487. +  BOOL secured_redirect = False;
  9488. +
  9489. +  struct in_addr ip, from_ip;
  9490. +  int search = 0;
  9491. +  
  9492. +  putip((char *)&from_ip,&nmb->additional->rdata[2]);
  9493. +  ip = from_ip;
  9494. +  
  9495. +  DEBUG(3,("Name registration for name %s at %s\n",
  9496. +               namestr(question),inet_ntoa(ip)));
  9497. +  
  9498. +  if (group)
  9499. +    {
  9500. +      /* apparently we should return 255.255.255.255 for group queries
  9501. +     (email from MS) */
  9502. +      ip = ipgrp;
  9503. +    }
  9504. +  
  9505. +  if (!(d = find_req_subnet(p->ip, bcast)))
  9506. +  {
  9507. +    DEBUG(3,("response packet: bcast %s not known\n",
  9508. +                inet_ntoa(p->ip)));
  9509. +    return;
  9510. +  }
  9511. +
  9512. +  if (bcast)
  9513. +    search &= FIND_LOCAL;
  9514. +  else
  9515. +    search &= FIND_WINS;
  9516. +
  9517. +  /* see if the name already exists */
  9518. +  n = find_name_search(&d, question, search, from_ip);
  9519. +  
  9520. +  if (n)
  9521. +  {
  9522. +    if (!group) /* unique names */
  9523. +    {
  9524. +      if (n->source == SELF || NAME_GROUP(n->nb_flags))
  9525. +      {
  9526. +          /* no-one can register one of samba's names, nor can they
  9527. +         register a name that's a group name as a unique name */
  9528. +          
  9529. +          success = False;
  9530. +      }
  9531. +      else if(!ip_equal(ip, n->ip))
  9532. +      {
  9533. +          /* XXXX rfc1001.txt says:
  9534. +           * if we are doing secured WINS, we must send a Wait-Acknowledge
  9535. +           * packet (WACK) to the person who wants the name, then do a
  9536. +           * name query on the person who currently owns the unique name.
  9537. +           * if the current owner still says they own it, the person who wants
  9538. +           * the name can't have it. if they do not, or are not alive, they can.
  9539. +           */
  9540. +
  9541. +          secured_redirect = True;
  9542. +
  9543. +          reply_name = &n->name;
  9544. +      }
  9545. +      else
  9546. +      {
  9547. +          n->ip = ip;
  9548. +          n->death_time = ttl?p->timestamp+ttl*3:0;
  9549. +          DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip)));
  9550. +      }
  9551. +    }
  9552. +    else
  9553. +    {
  9554. +      /* refresh the name */
  9555. +      if (n->source != SELF)
  9556. +      {
  9557. +          n->death_time = ttl?p->timestamp + ttl*3:0;
  9558. +      }
  9559. +    }
  9560. +
  9561. +    /* XXXX bug reported by terryt@ren.pc.athabascau.ca */
  9562. +    /* names that people have checked for and not found get DNSFAILed. 
  9563. +       we need to update the name record if someone then registers */
  9564. +
  9565. +    if (n->source == DNSFAIL)
  9566. +      n->source = REGISTER;
  9567. +
  9568. +  }
  9569. +  else
  9570. +  {
  9571. +      /* add the name to our name/subnet, or WINS, database */
  9572. +      n = add_netbios_entry(d,qname,qname_type,nb_flags,ttl,REGISTER,ip,
  9573. +                True,!bcast);
  9574. +  }
  9575. +  
  9576. +  /* if samba owns a unique name on a subnet, then it must respond and
  9577. +     disallow the attempted registration. if the registration is
  9578. +     successful by broadcast, only then is there no need to respond
  9579. +     (implicit registration: see rfc1001.txt 15.2.1).
  9580. +   */
  9581. +
  9582. +  if (bcast && success) return;
  9583. +  
  9584. +  if (secured_redirect)
  9585. +  {
  9586. +    char rdata[2];
  9587. +
  9588. +    /* XXXX luke is confused. RSVAL or SSVAL? assume NMB byte ordering */
  9589. +    RSSVAL(rdata,0,(nmb->header.opcode&0xf) + ((nb_flags&0xff) << 4));
  9590. +  
  9591. +    /* XXXX mistake in rfc1002.txt? 4.2.16: NULL is 0xa see 4.2.1.3 
  9592. +       type  = 0x0a; see rfc1002.txt 4.2.1.3 
  9593. +       class = 0x01; see rfc1002.txt 4.2.16
  9594. +     */
  9595. +
  9596. +    /* send WAIT ACKNOWLEDGEMENT see rfc1002.txt 4.2.16 */
  9597. +    reply_netbios_packet(p,nmb->header.name_trn_id,
  9598. +               0,NMB_WAIT_ACK,NMB_WAIT_ACK,False,
  9599. +               reply_name, 0x0a, 0x01,
  9600. +               15*1000, /* 15 seconds long enough to wait? */
  9601. +               rdata, 2);
  9602. +
  9603. +    /* initiate some enquiries to the current owner. */
  9604. +    queue_netbios_packet(d,ClientNMB,NMB_QUERY,
  9605. +                         NAME_REGISTER_CHALLENGE,
  9606. +                         reply_name->name,reply_name->name_type,nb_flags,0,
  9607. +                         False, False, n->ip, p->ip);
  9608. +  }
  9609. +  else
  9610. +  {
  9611. +    /* Send a NAME REGISTRATION RESPONSE (pos/neg) see rfc1002.txt 4.2.13-14
  9612. +       or an END-NODE CHALLENGE REGISTRATION RESPONSE see rfc1002.txt 4.2.7
  9613. +     */
  9614. +
  9615. +      send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REG,
  9616. +                        success, True,
  9617. +                        reply_name, nb_flags, ttl, ip);
  9618. +  }
  9619. +}
  9620. +
  9621. +
  9622. +/****************************************************************************
  9623. +reply to a name status query
  9624. +****************************************************************************/
  9625. +void reply_name_status(struct packet_struct *p)
  9626. +{
  9627. +  struct nmb_packet *nmb = &p->packet.nmb;
  9628. +  char *qname   = nmb->question.question_name.name;
  9629. +  int ques_type = nmb->question.question_name.name_type;
  9630. +  char rdata[MAX_DGRAM_SIZE];
  9631. +  char *countptr, *buf, *bufend;
  9632. +  int names_added;
  9633. +  struct name_record *n;
  9634. +  struct subnet_record *d = NULL;
  9635. +  int search = FIND_SELF;
  9636. +
  9637. +  BOOL bcast = nmb->header.nm_flags.bcast;
  9638. +  
  9639. +  if (!(d = find_req_subnet(p->ip, bcast)))
  9640. +  {
  9641. +    DEBUG(3,("Name status req: bcast %s not known\n",
  9642. +            inet_ntoa(p->ip)));
  9643. +    return;
  9644. +  }
  9645. +
  9646. +  DEBUG(3,("Name status for name %s %s\n",
  9647. +       namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
  9648. +  
  9649. +  if (bcast)
  9650. +    search |= FIND_WINS;
  9651. +  else
  9652. +    search |= FIND_LOCAL;
  9653. +
  9654. +  n = find_name_search(&d, &nmb->question.question_name,
  9655. +                search, p->ip);
  9656. +  
  9657. +  if (!n) return;
  9658. +  
  9659. +  /* XXXX hack, we should calculate exactly how many will fit */
  9660. +  bufend = &rdata[MAX_DGRAM_SIZE] - 18;
  9661. +  countptr = buf = rdata;
  9662. +  buf += 1;
  9663. +  
  9664. +  names_added = 0;
  9665. +  
  9666. +  for (n = d->namelist ; n && buf < bufend; n = n->next) 
  9667. +    {
  9668. +      int name_type = n->name.name_type;
  9669. +      
  9670. +      if (n->source != SELF) continue;
  9671. +      
  9672. +      /* start with first bit of putting info in buffer: the name */
  9673. +      
  9674. +      bzero(buf,18);
  9675. +      sprintf(buf,"%-15.15s",n->name.name);
  9676. +      strupper(buf);
  9677. +      
  9678. +      /* now check if we want to exclude other workgroup names
  9679. +     from the response. if we don't exclude them, windows clients
  9680. +     get confused and will respond with an error for NET VIEW */
  9681. +      
  9682. +      if (name_type >= 0x1b && name_type <= 0x20 && 
  9683. +      ques_type >= 0x1b && ques_type <= 0x20)
  9684. +    {
  9685. +      if (!strequal(qname, n->name.name)) continue;
  9686. +    }
  9687. +      
  9688. +      /* carry on putting name info in buffer */
  9689. +      
  9690. +      buf[15] = name_type;
  9691. +      buf[16]  = n->nb_flags;
  9692. +      
  9693. +      buf += 18;
  9694. +      
  9695. +      names_added++;
  9696. +    }
  9697. +  
  9698. +  SCVAL(countptr,0,names_added);
  9699. +  
  9700. +  /* XXXXXXX we should fill in more fields of the statistics structure */
  9701. +  bzero(buf,64);
  9702. +  {
  9703. +    extern int num_good_sends,num_good_receives;
  9704. +    SIVAL(buf,20,num_good_sends);
  9705. +    SIVAL(buf,24,num_good_receives);
  9706. +  }
  9707. +  
  9708. +  SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
  9709. +  
  9710. +  buf += 64;
  9711. +  
  9712. +  /* Send a POSITIVE NAME STATUS RESPONSE */
  9713. +  reply_netbios_packet(p,nmb->header.name_trn_id,
  9714. +               0,NMB_STATUS,0,True,
  9715. +               &nmb->question.question_name,
  9716. +               nmb->question.question_type,
  9717. +               nmb->question.question_class,
  9718. +               0,
  9719. +               rdata,PTR_DIFF(buf,rdata));
  9720. +}
  9721. +
  9722. +
  9723. +/***************************************************************************
  9724. +reply to a name query.
  9725. +
  9726. +with broadcast name queries:
  9727. +
  9728. +    - only reply if the query is for one of YOUR names. all other machines on
  9729. +      the network will be doing the same thing (that is, only replying to a
  9730. +      broadcast query if they own it)
  9731. +      NOTE: broadcast name queries should only be sent out by a machine
  9732. +      if they HAVEN'T been configured to use WINS. this is generally bad news
  9733. +      in a wide area tcp/ip network and should be rectified by the systems
  9734. +      administrator. USE WINS! :-)
  9735. +    - the exception to this is if the query is for a Primary Domain Controller
  9736. +      type name (0x1b), in which case, a reply is sent.
  9737. +
  9738. +    - NEVER send a negative response to a broadcast query. no-one else will!
  9739. +
  9740. +with directed name queries:
  9741. +
  9742. +    - if you are the WINS server, you are expected to respond with either
  9743. +      a negative response, a positive response, or a wait-for-acknowledgement
  9744. +      packet, and then later on a pos/neg response.
  9745. +
  9746. +****************************************************************************/
  9747. +void reply_name_query(struct packet_struct *p)
  9748. +{
  9749. +  struct nmb_packet *nmb = &p->packet.nmb;
  9750. +  struct nmb_name *question = &nmb->question.question_name;
  9751. +  int name_type = question->name_type;
  9752. +  BOOL bcast = nmb->header.nm_flags.bcast;
  9753. +  int ttl=0;
  9754. +  int rcode = 0;
  9755. +  int nb_flags = 0;
  9756. +  struct in_addr retip;
  9757. +  char rdata[6];
  9758. +  struct subnet_record *d = NULL;
  9759. +  BOOL success = True;
  9760. +  struct name_record *n;
  9761. +
  9762. +  /* directed queries are for WINS server: broadcasts are local SELF queries.
  9763. +     the exception is PDC names.  */
  9764. +
  9765. +  int search = bcast ? FIND_LOCAL | FIND_SELF : FIND_WINS;
  9766. +  
  9767. +  if (name_type == 0x1b)
  9768. +  {
  9769. +    /* even if it's a broadcast, we don't ignore queries for PDC names */
  9770. +    search = FIND_WINS;
  9771. +  }
  9772. +
  9773. +  if (search | FIND_LOCAL)
  9774. +  {
  9775. +    if (!(d = find_req_subnet(p->ip, bcast)))
  9776. +    {
  9777. +      DEBUG(3,("name query: bcast %s not known\n",
  9778. +                    inet_ntoa(p->ip)));
  9779. +      success = False;
  9780. +    }
  9781. +  }
  9782. +  else
  9783. +  {
  9784. +    if (!(d = find_subnet(ipgrp)))
  9785. +    {
  9786. +      DEBUG(3,("name query: wins search %s not known\n",
  9787. +                    inet_ntoa(p->ip)));
  9788. +      success = False;
  9789. +    }
  9790. +  }
  9791. +
  9792. +  DEBUG(3,("Name query "));
  9793. +  
  9794. +  if (search == 0)
  9795. +  {
  9796. +    /* eh? no criterion for searching database. help! */
  9797. +    success = False;
  9798. +  }
  9799. +
  9800. +  if (success && (n = search_for_name(&d,question,p->ip,p->timestamp, search)))
  9801. +  {
  9802. +      /* don't respond to broadcast queries unless the query is for
  9803. +         a name we own or it is for a Primary Domain Controller name */
  9804. +
  9805. +      if (bcast && n->source != SELF && name_type != 0x1b) {
  9806. +        if (!lp_wins_proxy() || same_net(p->ip,n->ip,*iface_nmask(p->ip))) {
  9807. +          /* never reply with a negative response to broadcast queries */
  9808. +          return;
  9809. +        }
  9810. +      }
  9811. +      
  9812. +      /* name is directed query, or it's self, or it's a PDC type name, or
  9813. +         we're replying on behalf of a caller because they are on a different
  9814. +         subnet and cannot hear the broadcast. XXXX lp_wins_proxy should be
  9815. +         switched off in environments where broadcasts are forwarded */
  9816. +
  9817. +      /* XXXX note: for proxy servers, we should forward the query on to
  9818. +         another WINS server if the name is not in our database, or we are
  9819. +         not a WINS server ourselves
  9820. +       */
  9821. +      ttl = n->death_time ? n->death_time - p->timestamp : GET_TTL(0);
  9822. +      retip = n->ip;
  9823. +      nb_flags = n->nb_flags;
  9824. +  }
  9825. +  else
  9826. +  {
  9827. +      if (bcast) return; /* never reply negative response to bcasts */
  9828. +      success = False;
  9829. +  }
  9830. +  
  9831. +  /* if the IP is 0 then substitute my IP */
  9832. +  if (zero_ip(retip)) retip = *iface_ip(p->ip);
  9833. +
  9834. +  if (success)
  9835. +  {
  9836. +      rcode = 0;
  9837. +      DEBUG(3,("OK %s\n",inet_ntoa(retip)));      
  9838. +  }
  9839. +  else
  9840. +  {
  9841. +      rcode = 3;
  9842. +      DEBUG(3,("UNKNOWN\n"));      
  9843. +  }
  9844. +  
  9845. +  if (success)
  9846. +  {
  9847. +      rdata[0] = nb_flags;
  9848. +      rdata[1] = 0;
  9849. +      putip(&rdata[2],(char *)&retip);
  9850. +  }
  9851. +  
  9852. +  reply_netbios_packet(p,nmb->header.name_trn_id,
  9853. +               rcode,NMB_QUERY,0,True,
  9854. +               &nmb->question.question_name,
  9855. +               nmb->question.question_type,
  9856. +               nmb->question.question_class,
  9857. +               ttl,
  9858. +               rdata, success ? 6 : 0);
  9859. +}
  9860. +
  9861. +
  9862. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameservreply.doc samba-1.9.16alpha11/source/nameservreply.doc
  9863. --- samba-1.9.16alpha10/source/nameservreply.doc    Thu Jan  1 10:00:00 1970
  9864. +++ samba-1.9.16alpha11/source/nameservreply.doc    Thu Jul 11 04:48:28 1996
  9865. @@ -0,0 +1,186 @@
  9866. +/*************************************************************************
  9867. +  reply_name_query()
  9868. +  *************************************************************************/
  9869. +
  9870. +this function is responsible for replying to a NetBIOS name query.
  9871. +
  9872. +there are two kinds of name queries: directed, and broadcast. directed
  9873. +queries are usually sent to samba in its WINS capacity. such hosts are
  9874. +termed 'point-to-point' hosts. broadcast queries are usually sent from
  9875. +'broadcast' or 'mixed' hosts.
  9876. +
  9877. +broadcasting is used by either older NetBIOS hosts, new NetBIOS hosts that
  9878. +have not had WINS capabilities added and new NetBIOS hosts that think the
  9879. +WINS server has died.
  9880. +
  9881. +the samba NetBIOS name database is divided into sections, on a
  9882. +per-subnet basis. there is also a WINS NetBIOS name database, and for
  9883. +convenience this is added as a pseudo-subnet with the ip address of
  9884. +255.255.255.255.
  9885. +
  9886. +the local subnet NetBIOS name databases only contain samba's names.
  9887. +the reason for this is that if a broadcast query is received, a NetBIOS
  9888. +hosts is only expected to respond if that query is for one of its own
  9889. +names (the exception to this is if a host is configured as a 'proxy'
  9890. +server, in which case, samba should redirect the query to another WINS
  9891. +server).
  9892. +
  9893. +the WINS pseudo-subnet NetBIOS database contains all NetBIOS names
  9894. +that are not 'special browser' type names (regarding this i am a
  9895. +_bit_ confused :-). names of type 0x01, 0x1d and 0x1e i consider to
  9896. +be 'special browser' names. at the moment. maybe.
  9897. +
  9898. +the type of search to be initiated is determined. if the NetBIOS name
  9899. +type is a non-special-browser name, then the WINS database is included
  9900. +in the search.
  9901. +
  9902. +if the name is not a special browser name, then we need to find the
  9903. +right subnet that the query came from. this is done using
  9904. +find_req_subnet(). this also has the benefit of stopping any queries
  9905. +from subnets that samba does not know about.
  9906. +
  9907. +if the query is a broadcast query, then the database of the local subnet
  9908. +is included in the search.
  9909. +
  9910. +the name is then searched for in the appropriate NetBIOS data structures.
  9911. +if it is found, then we need to check whether it is appropriate for us
  9912. +to reply to such a query.
  9913. +
  9914. +we will only reply if the query is a directed query, the name belongs to
  9915. +samba on that subnet, or the name is a primary domain controller type,
  9916. +or we're doing replies on behalf of hosts on subnets not known to the
  9917. +host issuing the query. in the latter instance, it would be appropriate
  9918. +if samba is using a WINS server for it to forward the name query on to
  9919. +this WINS server.
  9920. +
  9921. +reply_name_query() then takes note of all the information that is
  9922. +needed to construct a reply to the caller. a negative reply (if the
  9923. +name is unknown to samba) or a positive reply (the name is known to
  9924. +samba) is then issued.
  9925. +
  9926. +
  9927. +/*************************************************************************
  9928. +  reply_name_status()
  9929. +  *************************************************************************/
  9930. +
  9931. +this function is responsible for constructing a reply to a NetBIOS
  9932. +name status query. this response contains all samba's NetBIOS names
  9933. +on the subnet that the query came in from.
  9934. +
  9935. +a reply will only be made if the NetBIOS name being queried exists.
  9936. +
  9937. +see rfc1001.txt and rfc1002.txt for details of the name status reply.
  9938. +
  9939. +
  9940. +/*************************************************************************
  9941. +  reply_name_reg()
  9942. +  *************************************************************************/
  9943. +
  9944. +this function is responsible for updating the NetBIOS name database
  9945. +from registration packets sent out by hosts wishing to register a
  9946. +name, and for informing them, if necessary, if this is acceptable
  9947. +or not.
  9948. +
  9949. +name registration can be done by broadcast or by point-to-point,
  9950. +i.e the registration is sent directly to samba in its capacity as
  9951. +a WINS server.
  9952. +
  9953. +if the name registration is done by broadcast (see rfc1001.txt 15.2.1),
  9954. +then samba's involvement in replying is limited to whether that name
  9955. +is owned by samba or not, on the relevant subnet.
  9956. +
  9957. +if the name registration is done point-to-point (see rfc1001.txt 15.2.2)
  9958. +then samba will first need to check its WINS name database records and
  9959. +proceed accordingly.
  9960. +
  9961. +samba looks for the appropriate subnet record that the registration
  9962. +should be added to / checked against, using find_req_subnet().
  9963. +
  9964. +next, the name is searched for in the local database or the WINS
  9965. +database as appropriate.
  9966. +
  9967. +if the name is not found, then it is added to the NetBIOS name database,
  9968. +using add_netbios_entry(), which may choose not to add the name (not
  9969. +that this affects the registration of the name on the network in any way).
  9970. +it will only add names to the WINS database, and even then it will only
  9971. +add non-special-browser type names.
  9972. +
  9973. +if the name is found, then samba must decide whether to accept the name
  9974. +or not. a group name is always added. for unique names, further checks
  9975. +need to be carried out.
  9976. +
  9977. +firstly, if the name in the database is one of samba's names, or if the
  9978. +name in the database is a group name, then it cannot be added as a unique
  9979. +name belonging to someone else. it is therefore rejected.
  9980. +
  9981. +secondly, if the ip address of the name being registered does not match
  9982. +against the ip in the database, then the unique name may belong to
  9983. +someone else. a check needs to be carried out with the owner in case
  9984. +they still wish to keep this name. a detailed discussion of what action
  9985. +to take is in rfc1001.txt 15.2.2.2 and 15.2.2.3.
  9986. +
  9987. +samba currently implements non-secured WINS, whereupon the responsibility
  9988. +for checking the name is passed on to the host doing the registration.
  9989. +rfc1001.txt refers to this as an END-NODE CHALLENGE REGISTRATION RESPONSE.
  9990. +(samba itself cannot yet cope with receiving such responses if it
  9991. +registers its names with another WINS server). 
  9992. +
  9993. +having decided what kind of response to send (if any - acceptance of
  9994. +name registrations by broadcast is implicit), samba will send either a
  9995. +positive or negative NAME REGISTRATION RESPONSE, or an END-NODE CHALLENGE
  9996. +REGISTRATION RESPONSE to the host that initially sent the registration.
  9997. +
  9998. +whew.
  9999. +
  10000. +
  10001. +/*************************************************************************
  10002. +  reply_name_release()
  10003. +  *************************************************************************/
  10004. +
  10005. +this function is responsible for removing a NetBIOS name from the
  10006. +database when a server sends a release packet.
  10007. +
  10008. +samba looks for the appropriate subnet record that the release should
  10009. +be removed from, using find_req_subnet(). next, the name is searched
  10010. +for in the local database or the WINS database as appropriate.
  10011. +
  10012. +if the name is found, it is removed from the database and a
  10013. +positive reply is sent confirming this. if the name is not
  10014. +found, a negative reply is sent.
  10015. +
  10016. +a reply is _not_ sent if the release was done by broadcast: the
  10017. +release is implicit, and we should be grateful that they bothered
  10018. +to tell us. if the release was done by directed packet, then
  10019. +we deal with it as a WINS server and must reply (pos / neg).
  10020. +
  10021. +at present, the criteria for removing a name have yet to be
  10022. +developed / experimented with. at present, the only flags that
  10023. +are checked are the NetBIOS flags.
  10024. +
  10025. +
  10026. +/*************************************************************************
  10027. +  send_name_response()
  10028. +  *************************************************************************/
  10029. +
  10030. +this function is a wrap around reply_netbios_packet(). it sends
  10031. +a response to a name registration or release packet, minimising
  10032. +the function parameters needed to do this.
  10033. +
  10034. +if the function is called with the parameter 'success' set to
  10035. +True, then a positive response (to the registration or release)
  10036. +is made (see rfc1002.txt 4.2.5 and 4.2.10). if this parameter
  10037. +is False, then a negative response is issued (see rfc1002.txt
  10038. +4.2.6 and 4.2.11)
  10039. +
  10040. +if the function is called with a registration code, and the
  10041. +parameter 'recurse' is False, then an End-Node Challenge
  10042. +Registration response is issued (see rfc1002.txt 4.2.7)
  10043. +
  10044. +note: this function could also easily be used for name conflict
  10045. +demand (see rfc1002.txt 4.2.8).
  10046. +
  10047. +note: End-Node Challenge Registration response is only sent in
  10048. +non-secured NetBIOS Name Server implementations. samba now
  10049. +implements secured NetBIOS Name Server functionality (see
  10050. +rfc1001.txt 15.1.6).
  10051. +
  10052. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameservresp.c samba-1.9.16alpha11/source/nameservresp.c
  10053. --- samba-1.9.16alpha10/source/nameservresp.c    Thu Jan  1 10:00:00 1970
  10054. +++ samba-1.9.16alpha11/source/nameservresp.c    Thu Jul 18 20:53:16 1996
  10055. @@ -0,0 +1,743 @@
  10056. +/* 
  10057. +   Unix SMB/Netbios implementation.
  10058. +   Version 1.9.
  10059. +   NBT netbios routines and daemon - version 2
  10060. +   Copyright (C) Andrew Tridgell 1994-1996
  10061. +   
  10062. +   This program is free software; you can redistribute it and/or modify
  10063. +   it under the terms of the GNU General Public License as published by
  10064. +   the Free Software Foundation; either version 2 of the License, or
  10065. +   (at your option) any later version.
  10066. +   
  10067. +   This program is distributed in the hope that it will be useful,
  10068. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  10069. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10070. +   GNU General Public License for more details.
  10071. +   
  10072. +   You should have received a copy of the GNU General Public License
  10073. +   along with this program; if not, write to the Free Software
  10074. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  10075. +   
  10076. +   Revision History:
  10077. +
  10078. +   Module name: nameservresp.c
  10079. +
  10080. +   14 jan 96: lkcl@pires.co.uk
  10081. +   added multiple workgroup domain master support
  10082. +
  10083. +   05 jul 96: lkcl@pires.co.uk
  10084. +   created module nameservresp containing NetBIOS response functions
  10085. +
  10086. +*/
  10087. +
  10088. +#include "includes.h"
  10089. +
  10090. +extern int ClientNMB;
  10091. +
  10092. +extern int DEBUGLEVEL;
  10093. +
  10094. +extern pstring scope;
  10095. +extern struct in_addr ipzero;
  10096. +
  10097. +#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
  10098. +
  10099. +
  10100. +/****************************************************************************
  10101. +  response for a reg release received. samba has asked a WINS server if it
  10102. +  could release a name.
  10103. +  **************************************************************************/
  10104. +static void response_name_release(struct subnet_record *d,
  10105. +                                struct packet_struct *p)
  10106. +{
  10107. +  struct nmb_packet *nmb = &p->packet.nmb;
  10108. +  char *name = nmb->question.question_name.name;
  10109. +  int   type = nmb->question.question_name.name_type;
  10110. +  
  10111. +  DEBUG(4,("response name release received\n"));
  10112. +  
  10113. +  if (nmb->header.rcode == 0 && nmb->answers->rdata)
  10114. +  {
  10115. +    /* IMPORTANT: see expire_netbios_response_entries() */
  10116. +
  10117. +    struct in_addr found_ip;
  10118. +    putip((char*)&found_ip,&nmb->answers->rdata[2]);
  10119. +      
  10120. +    /* NOTE: we only release our own names at present */
  10121. +    if (ismyip(found_ip))
  10122. +    {
  10123. +      name_unregister_work(d,name,type);
  10124. +    }
  10125. +    else
  10126. +    {
  10127. +      DEBUG(2,("name release for different ip! %s %s\n",
  10128. +                  inet_ntoa(found_ip),
  10129. +                  namestr(&nmb->question.question_name)));
  10130. +    }
  10131. +  }
  10132. +  else
  10133. +  {
  10134. +    DEBUG(2,("name release for %s rejected!\n",
  10135. +           namestr(&nmb->question.question_name)));
  10136. +
  10137. +    /* XXXX PANIC! what to do if it's one of samba's own names? */
  10138. +
  10139. +    /* XXXX do we honestly care if our name release was rejected? 
  10140. +       only if samba is issuing the release on behalf of some out-of-sync
  10141. +       server. if it's one of samba's SELF names, we don't care. */
  10142. +  }
  10143. +}
  10144. +
  10145. +
  10146. +/****************************************************************************
  10147. +response for a reg request received
  10148. +**************************************************************************/
  10149. +static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
  10150. +{
  10151. +  struct nmb_packet *nmb = &p->packet.nmb;
  10152. +  char *name = nmb->question.question_name.name;
  10153. +  int   type = nmb->question.question_name.name_type;
  10154. +  BOOL bcast = nmb->header.nm_flags.bcast;
  10155. +  
  10156. +  DEBUG(4,("response name registration received!\n"));
  10157. +  
  10158. +  if (nmb->header.rcode == 0 && nmb->answers->rdata)
  10159. +  {
  10160. +    /* IMPORTANT: see expire_netbios_response_entries() */
  10161. +
  10162. +    int nb_flags = nmb->answers->rdata[0];
  10163. +    int ttl = nmb->answers->ttl;
  10164. +    struct in_addr found_ip;
  10165. +
  10166. +    putip((char*)&found_ip,&nmb->answers->rdata[2]);
  10167. +      
  10168. +    name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
  10169. +  }
  10170. +  else
  10171. +  {
  10172. +    DEBUG(1,("name registration for %s rejected!\n",
  10173. +           namestr(&nmb->question.question_name)));
  10174. +
  10175. +    /* oh dear. we have problems. possibly unbecome a master browser. */
  10176. +    name_unregister_work(d,name,type);
  10177. +  }
  10178. +}
  10179. +
  10180. +
  10181. +/****************************************************************************
  10182. +  response from a name query server check. states of type NAME_QUERY_PDC_SRV_CHK,
  10183. +  NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
  10184. +  ****************************************************************************/
  10185. +static void response_server_check(struct nmb_name *ans_name, 
  10186. +        struct response_record *n, struct subnet_record *d)
  10187. +{
  10188. +    /* issue another state: this time to do a name status check */
  10189. +
  10190. +    enum state_type cmd = (n->state == NAME_QUERY_PDC_SRV_CHK) ?
  10191. +          NAME_STATUS_PDC_SRV_CHK : NAME_STATUS_SRV_CHK;
  10192. +
  10193. +    /* initiate a name status check on the server that replied */
  10194. +    queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
  10195. +                ans_name->name, ans_name->name_type,
  10196. +                0,0,
  10197. +                False,False,n->send_ip,n->reply_to_ip);
  10198. +}
  10199. +
  10200. +
  10201. +/****************************************************************************
  10202. +  interpret a node status response. this is pretty hacked: we need two bits of
  10203. +  info. a) the name of the workgroup b) the name of the server. it will also
  10204. +  add all the names it finds into the namelist.
  10205. +****************************************************************************/
  10206. +static BOOL interpret_node_status(struct subnet_record *d,
  10207. +                char *p, struct nmb_name *name,int t,
  10208. +               char *serv_name, struct in_addr ip, BOOL bcast)
  10209. +{
  10210. +  int level = t==0x20 ? 4 : 0;
  10211. +  int numnames = CVAL(p,0);
  10212. +  BOOL found = False;
  10213. +
  10214. +  DEBUG(level,("received %d names\n",numnames));
  10215. +
  10216. +  p += 1;
  10217. +
  10218. +  if (serv_name) *serv_name = 0;
  10219. +
  10220. +  while (numnames--)
  10221. +    {
  10222. +      char qname[17];
  10223. +      int type;
  10224. +      fstring flags;
  10225. +      int nb_flags;
  10226. +      
  10227. +      BOOL group = False;
  10228. +      BOOL add   = False;
  10229. +      
  10230. +      *flags = 0;
  10231. +      
  10232. +      StrnCpy(qname,p,15);
  10233. +      type = CVAL(p,15);
  10234. +      nb_flags = p[16];
  10235. +      trim_string(qname,NULL," ");
  10236. +      
  10237. +      p += 18;
  10238. +      
  10239. +      if (NAME_GROUP    (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
  10240. +      if (NAME_BFLAG    (nb_flags)) { strcat(flags,"B "); }
  10241. +      if (NAME_PFLAG    (nb_flags)) { strcat(flags,"P "); }
  10242. +      if (NAME_MFLAG    (nb_flags)) { strcat(flags,"M "); }
  10243. +      if (NAME__FLAG    (nb_flags)) { strcat(flags,"_ "); }
  10244. +      if (NAME_DEREG    (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
  10245. +      if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
  10246. +      if (NAME_ACTIVE   (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
  10247. +      if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
  10248. +      
  10249. +      /* might as well update our namelist while we're at it */
  10250. +      if (add)
  10251. +    {
  10252. +      struct in_addr nameip;
  10253. +      enum name_source src;
  10254. +      
  10255. +      if (ismyip(ip)) {
  10256. +        nameip = ipzero;
  10257. +        src = SELF;
  10258. +      } else {
  10259. +        nameip = ip;
  10260. +        src = STATUS_QUERY;
  10261. +      }
  10262. +      add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
  10263. +    } 
  10264. +
  10265. +      /* we want the server name */
  10266. +      if (serv_name && !*serv_name && !group && t == 0)
  10267. +    {
  10268. +      StrnCpy(serv_name,qname,15);
  10269. +      serv_name[15] = 0;
  10270. +    }
  10271. +      
  10272. +      /* looking for a name and type? */
  10273. +      if (name && !found && (t == type))
  10274. +    {
  10275. +      /* take a guess at some of the name types we're going to ask for.
  10276. +         evaluate whether they are group names or no... */
  10277. +      if (((t == 0x1b || t == 0x1d             ) && !group) ||
  10278. +          ((t == 0x20 || t == 0x1c || t == 0x1e) &&  group))
  10279. +        {
  10280. +          found = True;
  10281. +          make_nmb_name(name,qname,type,scope);
  10282. +        }
  10283. +    }
  10284. +      
  10285. +      DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
  10286. +    }
  10287. +  DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
  10288. +           IVAL(p,20),IVAL(p,24)));
  10289. +  return found;
  10290. +}
  10291. +
  10292. +
  10293. +/****************************************************************************
  10294. +  response from a name status check. states of type NAME_STATUS_PDC_SRV_CHK
  10295. +  and NAME_STATUS_SRV_CHK dealt with here.
  10296. +  ****************************************************************************/
  10297. +static void response_name_status_check(struct in_addr ip,
  10298. +        struct nmb_packet *nmb, BOOL bcast,
  10299. +        struct response_record *n, struct subnet_record *d)
  10300. +{
  10301. +    /* NMB_STATUS arrives: contains workgroup name and server name required.
  10302. +       amongst other things. */
  10303. +
  10304. +    struct nmb_name name;
  10305. +    fstring serv_name;
  10306. +
  10307. +    if (interpret_node_status(d,nmb->answers->rdata,
  10308. +                              &name,name.name_type,serv_name,ip,bcast))
  10309. +    {
  10310. +        if (*serv_name)
  10311. +        {
  10312. +            sync_server(n->state,serv_name,
  10313. +                        name.name,name.name_type, n->send_ip);
  10314. +        }
  10315. +    }
  10316. +    else
  10317. +    {
  10318. +        DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
  10319. +    }
  10320. +}
  10321. +
  10322. +
  10323. +/****************************************************************************
  10324. +  response from a name query for secured WINS registration. a state of
  10325. +  NAME_REGISTER_CHALLENGE is dealt with here.
  10326. +  ****************************************************************************/
  10327. +static void response_name_query_register(struct nmb_packet *nmb, 
  10328. +        struct nmb_name *ans_name, 
  10329. +        struct response_record *n, struct subnet_record *d)
  10330. +{
  10331. +    struct in_addr register_ip;
  10332. +    BOOL new_owner;
  10333. +
  10334. +    DEBUG(4, ("Name query at %s ip %s - ",
  10335. +          namestr(&n->name), inet_ntoa(n->send_ip)));
  10336. +
  10337. +    if (!name_equal(&n->name, ans_name))
  10338. +    {
  10339. +        /* someone gave us the wrong name as a reply. oops. */
  10340. +        /* XXXX should say to them 'oi! release that name!' */
  10341. +
  10342. +        DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
  10343. +        return;
  10344. +    }
  10345. +
  10346. +    if (nmb->header.rcode == 0 && nmb->answers->rdata)
  10347. +    {
  10348. +        /* we had sent out a name query to the current owner
  10349. +           of a name because someone else wanted it. now they
  10350. +           have responded saying that they still want the name,
  10351. +           so the other host can't have it.
  10352. +         */
  10353. +
  10354. +        /* first check all the details are correct */
  10355. +
  10356. +        int nb_flags = nmb->answers->rdata[0];
  10357. +        struct in_addr found_ip;
  10358. +
  10359. +        putip((char*)&found_ip,&nmb->answers->rdata[2]);
  10360. +
  10361. +        if (nb_flags != n->nb_flags)
  10362. +        {
  10363. +            /* someone gave us the wrong nb_flags as a reply. oops. */
  10364. +            /* XXXX should say to them 'oi! release that name!' */
  10365. +
  10366. +            DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
  10367. +            DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
  10368. +            return;
  10369. +        }
  10370. +
  10371. +        if (!ip_equal(n->send_ip, found_ip))
  10372. +        {
  10373. +            /* someone gave us the wrong ip as a reply. oops. */
  10374. +            /* XXXX should say to them 'oi! release that name!' */
  10375. +
  10376. +            DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
  10377. +            DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
  10378. +            return;
  10379. +        }
  10380. +
  10381. +        DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
  10382. +
  10383. +        /* fine: now tell the other host they can't have the name */
  10384. +        register_ip = n->send_ip;
  10385. +        new_owner = False;
  10386. +    }
  10387. +    else
  10388. +    {
  10389. +        DEBUG(4, (" NEGATIVE RESPONSE!\n"));
  10390. +
  10391. +        /* the owner didn't want the name: the other host can have it */
  10392. +        register_ip = n->reply_to_ip;
  10393. +        new_owner = True;
  10394. +    }
  10395. +
  10396. +    /* register the old or the new owners' ip */
  10397. +    add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
  10398. +                    GET_TTL(0), register_ip,
  10399. +                    new_owner, n->reply_to_ip);
  10400. +}
  10401. +
  10402. +
  10403. +/****************************************************************************
  10404. +  response from a name query to sync browse lists or to update our netbios
  10405. +  entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM 
  10406. +  ****************************************************************************/
  10407. +static void response_name_query_sync(struct nmb_packet *nmb, 
  10408. +        struct nmb_name *ans_name, BOOL bcast,
  10409. +        struct response_record *n, struct subnet_record *d)
  10410. +{
  10411. +    DEBUG(4, ("Name query at %s ip %s - ",
  10412. +          namestr(&n->name), inet_ntoa(n->send_ip)));
  10413. +
  10414. +    if (!name_equal(&n->name, ans_name))
  10415. +    {
  10416. +        /* someone gave us the wrong name as a reply. oops. */
  10417. +        DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
  10418. +        return;
  10419. +    }
  10420. +
  10421. +    if (nmb->header.rcode == 0 && nmb->answers->rdata)
  10422. +    {
  10423. +        int nb_flags = nmb->answers->rdata[0];
  10424. +        struct in_addr found_ip;
  10425. +
  10426. +        putip((char*)&found_ip,&nmb->answers->rdata[2]);
  10427. +
  10428. +        if (!ip_equal(n->send_ip, found_ip))
  10429. +        {
  10430. +            /* someone gave us the wrong ip as a reply. oops. */
  10431. +            DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
  10432. +            DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
  10433. +            return;
  10434. +        }
  10435. +
  10436. +        DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
  10437. +
  10438. +        if (n->state == NAME_QUERY_SYNC)
  10439. +        {
  10440. +            struct work_record *work = NULL;
  10441. +            if ((work = find_workgroupstruct(d, ans_name->name, False)))
  10442. +            {
  10443. +                /* the server is there: sync quick before it (possibly) dies! */
  10444. +                sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
  10445. +                            found_ip);
  10446. +            }
  10447. +        }
  10448. +        else
  10449. +        {
  10450. +            /* update our netbios name list (re-register it if necessary) */
  10451. +            add_netbios_entry(d, ans_name->name, ans_name->name_type,
  10452. +                                nb_flags,GET_TTL(0),REGISTER,
  10453. +                                found_ip,False,!bcast);
  10454. +        }
  10455. +    }
  10456. +    else
  10457. +    {
  10458. +        DEBUG(4, (" NEGATIVE RESPONSE!\n"));
  10459. +
  10460. +        if (n->state == NAME_QUERY_CONFIRM)
  10461. +        {
  10462. +            /* XXXX remove_netbios_entry()? */
  10463. +            /* lots of things we ought to do, here. if we get here,
  10464. +               then we're in a mess: our name database doesn't match
  10465. +               reality. sort it out
  10466. +             */
  10467. +              remove_netbios_name(d,n->name.name, n->name.name_type,
  10468. +                                REGISTER,n->send_ip);
  10469. +        }
  10470. +    }
  10471. +}
  10472. +
  10473. +
  10474. +/****************************************************************************
  10475. +  report the response record type
  10476. +  ****************************************************************************/
  10477. +static void debug_rr_type(int rr_type)
  10478. +{
  10479. +  switch (rr_type)
  10480. +  {
  10481. +      case NMB_STATUS: DEBUG(3,("Name status ")); break;
  10482. +      case NMB_QUERY : DEBUG(3,("Name query ")); break;
  10483. +      case NMB_REG   : DEBUG(3,("Name registration ")); break;
  10484. +      case NMB_REL   : DEBUG(3,("Name release ")); break;
  10485. +      default        : DEBUG(1,("wrong response packet type received")); break;
  10486. +  }
  10487. +}
  10488. +
  10489. +/****************************************************************************
  10490. +  report the response record nmbd state
  10491. +  ****************************************************************************/
  10492. +void debug_state_type(int state)
  10493. +{
  10494. +  /* report the state type to help debugging */
  10495. +  switch (state)
  10496. +  {
  10497. +    case NAME_QUERY_PDC_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
  10498. +    case NAME_QUERY_SRV_CHK     : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
  10499. +    case NAME_QUERY_FIND_MST    : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
  10500. +    case NAME_STATUS_PDC_SRV_CHK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
  10501. +    case NAME_STATUS_SRV_CHK    : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
  10502. +    case NAME_QUERY_MST_CHK     : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
  10503. +    case NAME_REGISTER          : DEBUG(4,("NAME_REGISTER\n")); break;
  10504. +    case NAME_REGISTER_CHALLENGE: DEBUG(4,("NAME_REGISTER_CHALLENGE\n")); break;
  10505. +    case NAME_RELEASE           : DEBUG(4,("NAME_RELEASE\n")); break;
  10506. +    case NAME_QUERY_CONFIRM     : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
  10507. +    case NAME_QUERY_SYNC        : DEBUG(4,("NAME_QUERY_SYNC\n")); break;
  10508. +    default: break;
  10509. +  }
  10510. +}
  10511. +
  10512. +/****************************************************************************
  10513. +  report any problems with the fact that a response has been received.
  10514. +
  10515. +  (responses for certain types of operations are only expected from one host)
  10516. +  ****************************************************************************/
  10517. +static BOOL response_problem_check(struct response_record *n,
  10518. +            struct nmb_packet *nmb, char *qname)
  10519. +{
  10520. +  switch (nmb->answers->rr_type)
  10521. +  {
  10522. +    case NMB_REL:
  10523. +    {
  10524. +        if (n->num_msgs > 1)
  10525. +        {
  10526. +            DEBUG(1,("more than one release name response received!\n"));
  10527. +            return True;
  10528. +        }
  10529. +        break;
  10530. +    }
  10531. +
  10532. +    case NMB_REG:
  10533. +    {
  10534. +        if (n->num_msgs > 1)
  10535. +        {
  10536. +            DEBUG(1,("more than one register name response received!\n"));
  10537. +            return True;
  10538. +        }
  10539. +        break;
  10540. +    }
  10541. +
  10542. +    case NMB_QUERY:
  10543. +    { 
  10544. +      if (n->num_msgs > 1)
  10545. +      {
  10546. +          if (nmb->header.rcode == 0 && nmb->answers->rdata)
  10547. +          {
  10548. +            int nb_flags = nmb->answers->rdata[0];
  10549. +
  10550. +            if ((!NAME_GROUP(nb_flags)))
  10551. +            {
  10552. +               /* oh dear. more than one person responded to a unique name.
  10553. +                  there is either a network problem, a configuration problem
  10554. +                  or a server is mis-behaving */
  10555. +
  10556. +               /* XXXX mark the name as in conflict, and then let the
  10557. +                  person who just responded know that they must also mark it
  10558. +                  as in conflict, and therefore must NOT use it.
  10559. +                  see rfc1001.txt 15.1.3.5 */
  10560. +                    
  10561. +               /* this may cause problems for some early versions of nmbd */
  10562. +
  10563. +               switch (n->state)
  10564. +               {
  10565. +                case NAME_QUERY_FIND_MST:
  10566. +                {
  10567. +                  /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
  10568. +                  return False;
  10569. +                }
  10570. +                case NAME_QUERY_PDC_SRV_CHK:
  10571. +                case NAME_QUERY_SRV_CHK:
  10572. +                case NAME_QUERY_MST_CHK:
  10573. +                {
  10574. +                  if (!strequal(qname,n->name.name))
  10575. +                  {
  10576. +                     /* one subnet, one master browser per workgroup */
  10577. +                     /* XXXX force an election? */
  10578. +
  10579. +                     DEBUG(3,("more than one master browser replied!\n"));
  10580. +                     return True;
  10581. +                    }
  10582. +                   break;
  10583. +                }
  10584. +                default: break;
  10585. +               }
  10586. +               DEBUG(3,("Unique Name conflict detected!\n"));
  10587. +               return True;
  10588. +            }
  10589. +          }
  10590. +          else
  10591. +          {
  10592. +             /* we have received a negative reply, having already received
  10593. +                at least one response (pos/neg). something's really wrong! */
  10594. +
  10595. +             DEBUG(3,("wierd name query problem detected!\n"));
  10596. +             return True;
  10597. +          }
  10598. +       }
  10599. +    }
  10600. +  }
  10601. +  return False;
  10602. +}
  10603. +
  10604. +/****************************************************************************
  10605. +  check that the response received is compatible with the response record
  10606. +  ****************************************************************************/
  10607. +static BOOL response_compatible(struct response_record *n,
  10608. +            struct nmb_packet *nmb)
  10609. +{
  10610. +  switch (n->state)
  10611. +  {
  10612. +    case NAME_RELEASE:
  10613. +    {
  10614. +          if (nmb->answers->rr_type != NMB_REL)
  10615. +        {
  10616. +            DEBUG(1,("Name release reply has wrong answer rr_type\n"));
  10617. +            return False;
  10618. +        }
  10619. +        break;
  10620. +    }
  10621. +
  10622. +    case NAME_REGISTER:
  10623. +    {
  10624. +          if (nmb->answers->rr_type != NMB_REG)
  10625. +        {
  10626. +            DEBUG(1,("Name register reply has wrong answer rr_type\n"));
  10627. +            return False;
  10628. +        }
  10629. +        break;
  10630. +    }
  10631. +
  10632. +    case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
  10633. +    case NAME_QUERY_CONFIRM:
  10634. +    case NAME_QUERY_SYNC:
  10635. +    case NAME_QUERY_PDC_SRV_CHK:
  10636. +    case NAME_QUERY_SRV_CHK:
  10637. +    case NAME_QUERY_FIND_MST:
  10638. +    case NAME_QUERY_MST_CHK:
  10639. +    {
  10640. +        if (nmb->answers->rr_type != NMB_QUERY)
  10641. +        {
  10642. +            DEBUG(1,("Name query reply has wrong answer rr_type\n"));
  10643. +            return False;
  10644. +        }
  10645. +        break;
  10646. +    }
  10647. +      
  10648. +    case NAME_STATUS_PDC_SRV_CHK:
  10649. +    case NAME_STATUS_SRV_CHK:
  10650. +    {
  10651. +        if (nmb->answers->rr_type != NMB_STATUS)
  10652. +        {
  10653. +            DEBUG(1,("Name status reply has wrong answer rr_type\n"));
  10654. +            return False;
  10655. +        }
  10656. +        break;
  10657. +    }
  10658. +      
  10659. +    default:
  10660. +    {
  10661. +        DEBUG(1,("unknown state type received in response_netbios_packet\n"));
  10662. +        return False;
  10663. +    }
  10664. +  }
  10665. +  return True;
  10666. +}
  10667. +
  10668. +
  10669. +/****************************************************************************
  10670. +  process the response packet received
  10671. +  ****************************************************************************/
  10672. +static void response_process(struct subnet_record *d, struct packet_struct *p,
  10673. +                struct response_record *n, struct nmb_packet *nmb,
  10674. +                BOOL bcast, struct nmb_name *ans_name)
  10675. +{
  10676. +  switch (n->state)
  10677. +  {
  10678. +    case NAME_RELEASE:
  10679. +    {
  10680. +        response_name_release(d, p);
  10681. +        break;
  10682. +    }
  10683. +
  10684. +    case NAME_REGISTER:
  10685. +    {
  10686. +           response_name_reg(d, p);
  10687. +        break;
  10688. +    }
  10689. +
  10690. +    case NAME_REGISTER_CHALLENGE:
  10691. +    {
  10692. +        response_name_query_register(nmb, ans_name, n, d);
  10693. +        break;
  10694. +    }
  10695. +
  10696. +    case NAME_QUERY_PDC_SRV_CHK:
  10697. +    case NAME_QUERY_SRV_CHK:
  10698. +    case NAME_QUERY_FIND_MST:
  10699. +    {
  10700. +        response_server_check(ans_name, n, d);
  10701. +        break;
  10702. +    }
  10703. +      
  10704. +    case NAME_STATUS_PDC_SRV_CHK:
  10705. +    case NAME_STATUS_SRV_CHK:
  10706. +    {
  10707. +        response_name_status_check(p->ip, nmb, bcast, n, d);
  10708. +        break;
  10709. +    }
  10710. +      
  10711. +    case NAME_QUERY_CONFIRM:
  10712. +    case NAME_QUERY_SYNC:
  10713. +    {
  10714. +        response_name_query_sync(nmb, ans_name, bcast, n, d);
  10715. +        break;
  10716. +    }
  10717. +    case NAME_QUERY_MST_CHK:
  10718. +    {
  10719. +        /* no action required here. it's when NO responses are received
  10720. +           that we need to do something. see expire_name_query_entries() */
  10721. +    
  10722. +        DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
  10723. +                    namestr(&n->name), inet_ntoa(n->send_ip)));
  10724. +        break;
  10725. +    }
  10726. +
  10727. +    default:
  10728. +    {
  10729. +        DEBUG(1,("unknown state type received in response_netbios_packet\n"));
  10730. +        break;
  10731. +    }
  10732. +  }
  10733. +}
  10734. +
  10735. +
  10736. +/****************************************************************************
  10737. +  response from a netbios packet.
  10738. +  ****************************************************************************/
  10739. +void response_netbios_packet(struct packet_struct *p)
  10740. +{
  10741. +  struct nmb_packet *nmb = &p->packet.nmb;
  10742. +  struct nmb_name *question = &nmb->question.question_name;
  10743. +  struct nmb_name *ans_name = NULL;
  10744. +  char *qname = question->name;
  10745. +  BOOL bcast = nmb->header.nm_flags.bcast;
  10746. +  struct response_record *n;
  10747. +  struct subnet_record *d = NULL;
  10748. +
  10749. +  if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
  10750. +    DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
  10751. +    return;
  10752. +  }
  10753. +
  10754. +  if (!d)
  10755. +  {
  10756. +    DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
  10757. +    return;
  10758. +  }
  10759. +
  10760. +  if (!same_net(d->bcast_ip, d->mask_ip, p->ip)) /* copes with WINS 'subnet' */
  10761. +  {
  10762. +    DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
  10763. +    DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
  10764. +    return;
  10765. +  }
  10766. +
  10767. +  if (nmb->answers == NULL)
  10768. +  {
  10769. +      /* hm. the packet received was a response, but with no answer. wierd! */
  10770. +      DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
  10771. +           inet_ntoa(p->ip), BOOLSTR(bcast)));
  10772. +      return;
  10773. +  }
  10774. +
  10775. +  ans_name = &nmb->answers->rr_name;
  10776. +  DEBUG(3,("response for %s from %s (bcast=%s)\n",
  10777. +       namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
  10778. +  
  10779. +  debug_rr_type(nmb->answers->rr_type);
  10780. +
  10781. +  n->num_msgs++; /* count number of responses received */
  10782. +  n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
  10783. +
  10784. +  debug_state_type(n->state);
  10785. +
  10786. +  /* problem checking: multiple responses etc */
  10787. +  if (response_problem_check(n, nmb, qname))
  10788. +    return;
  10789. +
  10790. +  /* now check whether the 'state' has received the correct type of response */
  10791. +  if (!response_compatible(n, nmb))
  10792. +    return;
  10793. +
  10794. +  /* now deal with the current state */
  10795. +  response_process(d, p, n, nmb, bcast, ans_name);
  10796. +}
  10797. +
  10798. +
  10799. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nameservresp.doc samba-1.9.16alpha11/source/nameservresp.doc
  10800. --- samba-1.9.16alpha10/source/nameservresp.doc    Thu Jan  1 10:00:00 1970
  10801. +++ samba-1.9.16alpha11/source/nameservresp.doc    Thu Jul 11 04:48:29 1996
  10802. @@ -0,0 +1,164 @@
  10803. +this module deals with the receipt of response packets. the
  10804. +response packets are expected to be received, and there is a
  10805. +record of this kept (see also: modules nameresp and namedbresp)
  10806. +
  10807. +point of interest to design purists: every function in this
  10808. +module is static except response_netbios_packet().
  10809. +
  10810. +/*************************************************************************
  10811. +  response_netbios_packet()
  10812. +  *************************************************************************/
  10813. +
  10814. +this function receives netbios response packets. the samba server
  10815. +(or a rogue tcp/ip system, or nmblookup) will have sent out a packet
  10816. +requesting a response. a client (or a rogue tcp/ip system) responds
  10817. +to that request.
  10818. +
  10819. +this function checks the validity of the packet it receives.
  10820. +the expected response records are searched for the transaction id,
  10821. +to see if it's a response expected by the samba server. if it isn't
  10822. +it's reported as such, and ignored.
  10823. +
  10824. +if the response is found, then the subnet it was expected from will
  10825. +also have been found. the subnet it actually came in on can be
  10826. +checked against the subnet it was expected from and reported,
  10827. +otherwise this function just carries on.
  10828. +
  10829. +the number of responses received is increased, and the number of
  10830. +retries left to be sent is set to zero.
  10831. +
  10832. +after debug information is reported, and validation of the netbios
  10833. +packet (e.g only one response from one machine is expected for some
  10834. +functions) has occurred, the packet is processed. when the initial
  10835. +request was sent out, the expected response record was flagged with,
  10836. +for lack of a better word, a samba 'state' type. whenever a
  10837. +response is received, the appropriate function is called to carry on
  10838. +where the program control flow was interrupted while awaiting exactly
  10839. +such a response.
  10840. +
  10841. +please note that _not_ receiving a response is dealt with in another
  10842. +area of code - expire_netbios_response_entries().
  10843. +
  10844. +
  10845. +/*************************************************************************
  10846. +  response_name_query_sync()
  10847. +  *************************************************************************/
  10848. +
  10849. +this function receives responses to samba 'states' NAME_QUERY_SYNC and
  10850. +NAME_QUERY_CONFIRM.
  10851. +
  10852. +NAME_QUERY_SYNC: name query a server before synchronising browse lists.
  10853. +NAME_QUERY_CONFIRM: name query a server to check that it's alive.
  10854. +
  10855. +a NAME_QUERY_SYNC will be carried out in order to check that a server
  10856. +is alive before syncing browse lists. we don't want to delay the SMB
  10857. +NetServerEnum api just because the server has gone down: we have too
  10858. +much else to do.
  10859. +
  10860. +a NAME_QUERY_CONFIRM is just a name query to see whether the server is
  10861. +alive.  these queries are sent out by samba's WINS server side, to verify
  10862. +its netbios name database of all machines that have registered with it.
  10863. +
  10864. +we don't normally expect a negative response from such a query, although
  10865. +we may do so if the query was sent to another WINS server. the registered
  10866. +entry should be removed if we receive a negative response.
  10867. +
  10868. +
  10869. +/*************************************************************************
  10870. +  response_name_status_check()
  10871. +  *************************************************************************/
  10872. +
  10873. +this function receives responses to samba 'states' NAME_STATUS_CHECK
  10874. +and NAME_STATUS_MASTER_CHECK
  10875. +
  10876. +NAME_STATUS_MASTER_CHECK: name status a primary domain controller, 
  10877. +                          confirm its domain and then initiate syncing
  10878. +                          its browse list.
  10879. +
  10880. +NAME_STATUS_CHECK: same as NAME_STATUS_MASTER_CHECK except the name status
  10881. +                   is issued to a master browser.
  10882. +
  10883. +if we don't know what workgroup a server is responsible for, but we
  10884. +know that there is a master browser at a certain ip, we can issue a
  10885. +name status check. from the response received, there will be
  10886. +a master browser netbios entry. this will allow us to synchronise
  10887. +browse lists with that machine and then add the information to the
  10888. +correct part of samba's workgroup - server database.
  10889. +
  10890. +
  10891. +/*************************************************************************
  10892. +  response_server_check()
  10893. +  *************************************************************************/
  10894. +
  10895. +this function receives responses to samba 'states' NAME_QUERY_MST_SRV_CHK,
  10896. +NAME_QUERY_SRV_CHK and NAME_QUERY_FIND_MST.
  10897. +
  10898. +NAME_QUERY_FIND_MST: issued as a broadcast when we wish to find out all
  10899. +                     master browsers (i.e all servers that have registered
  10900. +                     the NetBIOS name ^1^2__MSBROWSE__^2(0x1), and then
  10901. +                     issue a NAME_STATUS_MASTER_CHECK on any servers that
  10902. +                     respond, which will initiate a sync browse lists.
  10903. +
  10904. +NAME_QUERY_MST_SRV_CHK: same as a NAME_QUERY_FIND_MST except this is sent
  10905. +                        to a primary domain controller.
  10906. +
  10907. +NAME_QUERY_SRV_CHK: same as a NAME_QUERY_MST_SRV_CHK except this is sent to
  10908. +                    a master browser.
  10909. +                        
  10910. +the purpose of each of these states is to do a broadcast name query, or
  10911. +a name query directed at a WINS server, then to all hosts that respond,
  10912. +we issue a name status check, which will confirm for us the workgroup
  10913. +or domain name, and then initiate issuing a sync browse list call with
  10914. +that server.
  10915. +
  10916. +a NAME_QUERY_SRV_CHK is sent when samba receives a list of backup
  10917. +browsers. it checks to see if that server is alive (by doing a
  10918. +name query on a server) and then syncs browse lists with it.
  10919. +
  10920. +
  10921. +/*************************************************************************
  10922. +  response_name_reg()
  10923. +  *************************************************************************/
  10924. +
  10925. +this function is responsible for dealing with samba's registration
  10926. +attempts, by broadcast to a local subnet, or point-to-point with 
  10927. +another WINS server.
  10928. +
  10929. +please note that it cannot cope with END-NODE CHALLENGE REGISTRATION
  10930. +RESPONSEs at present.
  10931. +
  10932. +when a response is received, samba determines if the response is a
  10933. +positive or a negative one. if it is a positive response, the name
  10934. +is added to samba's database.
  10935. +
  10936. +when a negative response is received, samba will remove the name
  10937. +from its database. if, however, the name is a browser type (0x1b is
  10938. +a primary domain controller type name; or 0x1d, which is a master
  10939. +browser type name) then it must also stop being a primary domain
  10940. +controller or master browser respectively, depending on what kind
  10941. +of name was rejected.
  10942. +
  10943. +(when no response is received, then expire_netbios_response_entries()
  10944. +is expected to deal with this. the only case that is dealt with here
  10945. +at present is when the registration was done by broadcast. if there
  10946. +is no challenge to the broadcast registration, it is implicitly
  10947. +assumed that claiming the name is acceptable).
  10948. +
  10949. +
  10950. +/*************************************************************************
  10951. +  response_name_release()
  10952. +  *************************************************************************/
  10953. +
  10954. +this function is responsible for removing samba's NetBIOS name when
  10955. +samba contacts another WINS server with which it had registered the
  10956. +name.
  10957. +
  10958. +only positive name releases are expected and dealt with. exactly what
  10959. +to do if a negative name release (i.e someone says 'oi! you have to
  10960. +keep that name!') is received is uncertain.
  10961. +
  10962. +(when no response is received, then expire_netbios_response_entries()
  10963. +is expected to deal with this. if there is no challenge to the release
  10964. +of the name, the name is then removed from that subnet's NetBIOS
  10965. +name database).
  10966. +
  10967. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namework.c samba-1.9.16alpha11/source/namework.c
  10968. --- samba-1.9.16alpha10/source/namework.c    Mon Jun 10 15:18:56 1996
  10969. +++ samba-1.9.16alpha11/source/namework.c    Thu Jul 18 20:53:16 1996
  10970. @@ -2,7 +2,7 @@
  10971.     Unix SMB/Netbios implementation.
  10972.     Version 1.9.
  10973.     NBT netbios routines and daemon - version 2
  10974. -   Copyright (C) Andrew Tridgell 1994-1995
  10975. +   Copyright (C) Andrew Tridgell 1994-1996
  10976.     
  10977.     This program is free software; you can redistribute it and/or modify
  10978.     it under the terms of the GNU General Public License as published by
  10979. @@ -45,9 +45,6 @@
  10980.  
  10981.  extern int workgroup_count; /* total number of workgroups we know about */
  10982.  
  10983. -/* this is our browse cache database */
  10984. -extern struct browse_cache_record *browserlist;
  10985. -
  10986.  /* this is our domain/workgroup/server database */
  10987.  extern struct subnet_record *subnetlist;
  10988.  
  10989. @@ -67,13 +64,7 @@
  10990.  
  10991.  extern time_t StartupTime;
  10992.  
  10993. -#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
  10994. -#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
  10995. -
  10996. -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
  10997. -
  10998. -#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
  10999. -
  11000. +extern BOOL updatedlists;
  11001.  
  11002.  /****************************************************************************
  11003.  tell a server to become a backup browser
  11004. @@ -106,6 +97,11 @@
  11005.  **************************************************************************/
  11006.  void tell_become_backup(void)
  11007.  {
  11008. +  /* XXXX note: this function is currently unsuitable for use, as it
  11009. +     does not properly check that a server is in a fit state to become
  11010. +     a backup browser before asking it to be one.
  11011. +   */
  11012. +
  11013.    struct subnet_record *d;
  11014.    for (d = subnetlist; d; d = d->next)
  11015.      {
  11016. @@ -155,266 +151,6 @@
  11017.      }
  11018.  }
  11019.  
  11020. -/****************************************************************************
  11021. -find a server responsible for a workgroup, and sync browse lists
  11022. -**************************************************************************/
  11023. -static BOOL sync_browse_entry(struct browse_cache_record *b)
  11024. -{                     
  11025. -  struct subnet_record *d;
  11026. -  struct work_record *work;
  11027. -  /*
  11028. -    if (!strequal(serv_name, b->name))
  11029. -    {
  11030. -    DEBUG(0, ("browser's netbios name (%s) does not match %s (%s)",
  11031. -    b->name, inet_ntoa(b->ip), serv_name));
  11032. -    }
  11033. -    */
  11034. -  if (!(d = find_domain(b->ip))) return False;
  11035. -  if (!(work = find_workgroupstruct(d, b->group, False))) return False;
  11036. -  
  11037. -  if (AM_MASTER(work)) {
  11038. -    /* only try to sync browse lists if we are the master, otherwise
  11039. -       the net could get a little bit too busy */
  11040. -    sync_browse_lists(work,b->name,0x20,b->ip);
  11041. -  }
  11042. -  b->synced = True;
  11043. -  
  11044. -  return True;
  11045. -}
  11046. -
  11047. -
  11048. -/****************************************************************************
  11049. -search through browser list for an entry to sync with
  11050. -**************************************************************************/
  11051. -void do_browser_lists(void)
  11052. -{
  11053. -  struct browse_cache_record *b;
  11054. -  static time_t last = 0;
  11055. -  time_t t = time(NULL);
  11056. -  
  11057. -  if (t-last < 20) return; /* don't do too many of these at once! */
  11058. -  
  11059. -  last = t;
  11060. -  
  11061. -  /* pick any entry in the list, preferably one whose time is up */
  11062. -  for (b = browserlist; b && b->next; b = b->next)
  11063. -    {
  11064. -      if (b->sync_time < t && b->synced == False) break;
  11065. -    }
  11066. -  
  11067. -  if (!b || b->synced || sync_browse_entry(b))
  11068. -    {
  11069. -      /* leave entries (even ones already sync'd) for up to a minute.
  11070. -     this stops them getting re-sync'd too often */
  11071. -      expire_browse_cache(t - 60);
  11072. -    }
  11073. -}
  11074. -
  11075. -
  11076. -/****************************************************************************
  11077. -find a server responsible for a workgroup, and sync browse lists
  11078. -control ends up back here via response_name_query.
  11079. -**************************************************************************/
  11080. -void sync_server(enum cmd_type cmd, char *serv_name, char *work_name, 
  11081. -         int name_type,
  11082. -         struct in_addr ip)
  11083. -{                     
  11084. -  add_browser_entry(serv_name, name_type, work_name, 0, ip);
  11085. -
  11086. -  if (cmd == MASTER_SERVER_CHECK)
  11087. -    {
  11088. -      /* announce ourselves as a master browser to serv_name */
  11089. -      do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
  11090. -              0x20, 0, ip);
  11091. -    }
  11092. -}
  11093. -
  11094. -
  11095. -/****************************************************************************
  11096. -update workgroup database from a name registration
  11097. -**************************************************************************/
  11098. -void update_from_reg(char *name, int type, struct in_addr ip)
  11099. -{                     
  11100. -  /* default server type: minimum guess at requirement XXXX */
  11101. -
  11102. -  DEBUG(3,("update from registration: host %s ip %s type %0x\n",
  11103. -        name, inet_ntoa(ip), type));
  11104. -
  11105. -  /* workgroup types, but not a chat type */
  11106. -  if (type >= 0x1b && type <= 0x1e)
  11107. -    {
  11108. -      struct work_record *work;
  11109. -      struct subnet_record *d;
  11110. -      
  11111. -      if (!(d    = find_domain(ip))) return;
  11112. -      if (!(work = find_workgroupstruct(d, name, False))) return;
  11113. -      
  11114. -      /* request the server to announce if on our subnet */
  11115. -      if (d->my_interface) announce_request(work, ip);
  11116. -      
  11117. -      /* domain master type or master browser type */
  11118. -      if (type == 0x1b || type == 0x1d)
  11119. -    {
  11120. -      struct hostent *hp = gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
  11121. -      if (hp) {
  11122. -        /* gethostbyaddr name may not match netbios name but who cares */
  11123. -        add_browser_entry(hp->h_name, type, work->work_group, 120, ip);
  11124. -      }
  11125. -    }
  11126. -    }
  11127. -}
  11128. -
  11129. -
  11130. -/****************************************************************************
  11131. -  add the default workgroup into my domain
  11132. -  **************************************************************************/
  11133. -void add_my_domains(char *group)
  11134. -{
  11135. -  int n,i;
  11136. -  struct in_addr *ip;
  11137. -
  11138. -  if (*group == '*') return;
  11139. -
  11140. -  n = iface_count();
  11141. -  for (i=0;i<n;i++) {
  11142. -    ip = iface_n_ip(i);
  11143. -    if (!ip) return;
  11144. -    add_subnet_entry(*iface_bcast(*ip),*iface_nmask(*ip),lp_workgroup(),True);
  11145. -  }
  11146. -}
  11147. -
  11148. -
  11149. -/****************************************************************************
  11150. -  send a backup list response.
  11151. -  **************************************************************************/
  11152. -static void send_backup_list(char *work_name, struct nmb_name *src_name,
  11153. -                 int info_count, int token, int info,
  11154. -                 int name_type, struct in_addr ip)
  11155. -{                     
  11156. -  struct subnet_record *d;
  11157. -  char outbuf[1024];
  11158. -  char *p, *countptr, *nameptr;
  11159. -  int count = 0;
  11160. -  int i, j;
  11161. -  char *theirname = src_name->name;
  11162. -  
  11163. -  DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n", 
  11164. -       work_name, inet_ntoa(ip),
  11165. -       myname,0x20,theirname,0x0));       
  11166. -  
  11167. -  if (name_type == 0x1d)
  11168. -    {
  11169. -      DEBUG(4,("master browsers: "));
  11170. -    }
  11171. -  else if (name_type == 0x1b)
  11172. -    {
  11173. -      DEBUG(4,("domain controllers: "));
  11174. -    }
  11175. -  else
  11176. -    {
  11177. -      DEBUG(0,("backup request for unknown type %0x\n", name_type));
  11178. -      return;
  11179. -    }
  11180. -  
  11181. -  bzero(outbuf,sizeof(outbuf));
  11182. -  p = outbuf;
  11183. -  
  11184. -  CVAL(p,0) = 10;    /* backup list response */
  11185. -  p++;
  11186. -  
  11187. -  countptr = p; /* count pointer */
  11188. -  
  11189. -  SSVAL(p,1,token); /* sender's workgroup index representation */
  11190. -  SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
  11191. -  p += 5;
  11192. -  
  11193. -  nameptr = p;
  11194. -  
  11195. -  for (d = subnetlist; d; d = d->next)
  11196. -    {
  11197. -      struct work_record *work;
  11198. -      
  11199. -      for (work = d->workgrouplist; work; work = work->next)
  11200. -    {
  11201. -      struct server_record *s;
  11202. -      
  11203. -      if (!strequal(work->work_group, work_name)) continue;
  11204. -      
  11205. -      for (s = work->serverlist; s; s = s->next)
  11206. -        { 
  11207. -          BOOL found = False;
  11208. -          char *n;
  11209. -          
  11210. -          if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
  11211. -          
  11212. -          for (n = nameptr; n < p; n = skip_string(n, 1))
  11213. -        {
  11214. -          if (strequal(n, s->serv.name)) found = True;
  11215. -        }
  11216. -          
  11217. -          if (found) continue; /* exclude names already added */
  11218. -          
  11219. -          /* workgroup request: include all backup browsers in the list */
  11220. -          /* domain request: include all domain members in the list */
  11221. -          
  11222. -          if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
  11223. -          (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
  11224. -        {                          
  11225. -          DEBUG(4, ("%s ", s->serv.name));
  11226. -          
  11227. -          count++;
  11228. -          strcpy(p,s->serv.name);
  11229. -          strupper(p);
  11230. -          p = skip_string(p,1);
  11231. -        }
  11232. -        }
  11233. -    }
  11234. -    }
  11235. -  
  11236. -  if (count == 0)
  11237. -    {
  11238. -      DEBUG(4, ("none\n"));
  11239. -      return;
  11240. -    }
  11241. -  else
  11242. -    {
  11243. -      DEBUG(4, (" - count %d\n", count));
  11244. -    }
  11245. -  
  11246. -  CVAL(countptr,0) = count; /* total number of backup browsers found */
  11247. -  
  11248. -  {
  11249. -    int len = PTR_DIFF(p, outbuf);
  11250. -    
  11251. -    for (i = 0; i < len; i+= 16)
  11252. -      {
  11253. -    DEBUG(4, ("%3x char ", i));
  11254. -    
  11255. -    for (j = 0; j < 16; j++)
  11256. -      {
  11257. -        unsigned char x = outbuf[i+j];
  11258. -        if (x < 32 || x > 127) x = '.';
  11259. -        
  11260. -        if (i+j >= len) break;
  11261. -        DEBUG(4, ("%c", x));
  11262. -      }
  11263. -    
  11264. -    DEBUG(4, (" hex ", i));
  11265. -    
  11266. -    for (j = 0; j < 16; j++)
  11267. -      {
  11268. -        if (i+j >= len) break;
  11269. -        DEBUG(4, (" %02x", outbuf[i+j]));
  11270. -      }
  11271. -    
  11272. -    DEBUG(4, ("\n"));
  11273. -      }
  11274. -    
  11275. -  }
  11276. -  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  11277. -              myname,theirname,0x20,0,ip,*iface_ip(ip));
  11278. -}
  11279. -
  11280.  
  11281.  /*******************************************************************
  11282.    same context: scope. should check name_type as well, and makes sure
  11283. @@ -460,18 +196,22 @@
  11284.    resources. We just have to pass it to smbd (via browser.dat) and let
  11285.    the client choose using bit masks.
  11286.    ******************************************************************/
  11287. -static void process_announce(struct packet_struct *p,int command,char *buf)
  11288. +static void process_announce(struct packet_struct *p,uint16 command,char *buf)
  11289.  {
  11290.    struct dgram_packet *dgram = &p->packet.dgram;
  11291.    struct in_addr ip = dgram->header.source_ip;
  11292. -  struct subnet_record *d = find_domain(ip); 
  11293. +  struct subnet_record *d = find_subnet(ip); 
  11294.    int update_count = CVAL(buf,0);
  11295. +
  11296.    int ttl = IVAL(buf,1)/1000;
  11297.    char *name = buf+5;
  11298.    int osmajor=CVAL(buf,21);
  11299.    int osminor=CVAL(buf,22);
  11300.    uint32 servertype = IVAL(buf,23);
  11301. +  uint32 browse_type= CVAL(buf,27);
  11302. +  uint32 browse_sig = CVAL(buf,29);
  11303.    char *comment = buf+31;
  11304. +
  11305.    struct work_record *work;
  11306.    char *work_name;
  11307.    char *serv_name = dgram->source_name.name;
  11308. @@ -480,9 +220,9 @@
  11309.    comment[43] = 0;
  11310.    
  11311.    DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
  11312. -  DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
  11313. +  DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x sig=%4x %4x comment=%s\n",
  11314.         namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
  11315. -       servertype,comment));
  11316. +       servertype,browse_type,browse_sig,comment));
  11317.    
  11318.    name[15] = 0;  
  11319.    
  11320. @@ -501,10 +241,20 @@
  11321.        return;
  11322.      }
  11323.    
  11324. -  if (same_context(dgram)) return;
  11325. +  if (!strequal(dgram->dest_name.scope,scope )) return;
  11326.    
  11327. -  if (command == ANN_DomainAnnouncement) {
  11328. +  if (command == ANN_DomainAnnouncement) { 
  11329. +    /* XXXX if we are a master browser for the workgroup work_name,
  11330. +       then there is a local subnet configuration problem. only
  11331. +       we should be sending out such domain announcements, because
  11332. +       as the master browser, that is our job.
  11333. +
  11334. +       stop being a master browser, and force an election. this will
  11335. +       sort out the network problem. hopefully.
  11336. +     */
  11337. +
  11338.      work_name = name;
  11339. +    add = True;
  11340.    } else {
  11341.      work_name = dgram->dest_name.name;
  11342.    }
  11343. @@ -524,15 +274,24 @@
  11344.    
  11345.    ttl = GET_TTL(ttl);
  11346.    
  11347. -  /* add them to our browse list */
  11348. +  /* add them to our browse list, and update the browse.dat file */
  11349.    add_server_entry(d,work,name,servertype,ttl,comment,True);
  11350. -  
  11351. +  updatedlists = True;
  11352. +
  11353.  #if 0
  11354.    /* the tell become backup code is broken, no great harm is done by
  11355.       disabling it */
  11356.    tell_become_backup();
  11357.  #endif
  11358.  
  11359. +  /* XXXX over-kill: i don't think we should really be doing this,
  11360. +     but it doesn't do much harm other than to add extra network
  11361. +     traffic. to be more precise, we should (possibly) only
  11362. +     sync browse lists with a host that sends an
  11363. +     ANN_LocalMasterAnnouncement or an ANN_DomainAnnouncement.
  11364. +     possibly.
  11365. +   */
  11366. +
  11367.    /* get their browse list from them and add it to ours. */
  11368.    add_browser_entry(serv_name,dgram->dest_name.name_type,
  11369.              work->work_group,30,ip);
  11370. @@ -545,8 +304,8 @@
  11371.  {
  11372.    struct dgram_packet *dgram = &p->packet.dgram;
  11373.    struct in_addr ip = dgram->header.source_ip;
  11374. -  struct subnet_record *d = find_domain(ip);
  11375. -  struct subnet_record *mydomain = find_domain(*iface_bcast(ip));
  11376. +  struct subnet_record *d = find_subnet(ip);
  11377. +  struct subnet_record *mydomain = find_subnet(*iface_bcast(ip));
  11378.    char *name = buf;
  11379.    struct work_record *work;
  11380.    name[15] = 0;
  11381. @@ -575,18 +334,24 @@
  11382.    we receive a list of servers, and we attempt to locate them all on
  11383.    our local subnet, and sync browse lists with them on the workgroup
  11384.    they are said to be in.
  11385. +
  11386. +  XXXX NOTE: this function is in overdrive. it should not really do
  11387. +  half of what it actually does (it should pick _one_ name from the
  11388. +  list received and sync with it at regular intervals, rather than
  11389. +  sync with them all only once!)
  11390. +
  11391.    ******************************************************************/
  11392.  static void process_rcv_backup_list(struct packet_struct *p,char *buf)
  11393.  {
  11394.    struct dgram_packet *dgram = &p->packet.dgram;
  11395.    struct in_addr ip = dgram->header.source_ip;
  11396.    int count = CVAL(buf,0);
  11397. -  int Index = IVAL(buf,1); /* caller's index representing workgroup */
  11398. +  uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
  11399.    char *buf1;
  11400.    
  11401. -  DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
  11402. +  DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
  11403.         namestr(&dgram->dest_name), inet_ntoa(ip),
  11404. -       count, Index));
  11405. +       count, info));
  11406.    
  11407.    if (same_context(dgram)) return;
  11408.    
  11409. @@ -594,50 +359,170 @@
  11410.    
  11411.    /* go through the list of servers attempting to sync browse lists */
  11412.    for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
  11413. -    {
  11414. -      struct in_addr back_ip;
  11415. -      struct subnet_record *d;
  11416. +  {
  11417. +    struct in_addr back_ip;
  11418. +    struct subnet_record *d;
  11419.        
  11420. -      DEBUG(4,("Searching for backup browser %s at %s...\n",
  11421. +    DEBUG(4,("Searching for backup browser %s at %s...\n",
  11422.             buf1, inet_ntoa(ip)));
  11423.        
  11424. -      /* XXXX assume name is a DNS name NOT a netbios name. a more complete
  11425. -     approach is to use reply_name_query functionality to find the name */
  11426. -      back_ip = *interpret_addr2(buf1);
  11427. +    /* XXXX assume name is a DNS name NOT a netbios name. a more complete
  11428. +       approach is to use reply_name_query functionality to find the name */
  11429. +
  11430. +    back_ip = *interpret_addr2(buf1);
  11431.        
  11432. -      if (zero_ip(back_ip))
  11433. +    if (zero_ip(back_ip))
  11434.      {
  11435.        DEBUG(4,("Failed to find backup browser server using DNS\n"));
  11436.        continue;
  11437.      }
  11438.        
  11439.        DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
  11440. +      DEBUG(4,("END THIS LOOP: CODE NEEDS UPDATING\n"));
  11441.        
  11442. -      if ((d = find_domain(back_ip)))
  11443. +      /* XXXX function needs work */
  11444. +      continue;
  11445. +
  11446. +    if ((d = find_subnet(back_ip)))
  11447.      {
  11448.        struct subnet_record *d1;
  11449.        for (d1 = subnetlist; d1; d1 = d1->next)
  11450. -        {
  11451. +      {
  11452.            struct work_record *work;
  11453.            for (work = d1->workgrouplist; work; work = work->next)
  11454.          {
  11455. -          if (work->token == Index)
  11456. -            {
  11457. -              queue_netbios_packet(ClientNMB,NMB_QUERY,SERVER_CHECK,
  11458. -                       work->work_group,0x1d,0,
  11459. -                       False,False,back_ip);
  11460. +          if (work->token == 0 /* token */)
  11461. +          {
  11462. +              queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
  11463. +                       work->work_group,0x1d,0,0,
  11464. +                       False,False,back_ip,back_ip);
  11465.                return;
  11466. -            }
  11467. +          }
  11468.          }
  11469. -        }
  11470. +      }
  11471. +    }
  11472. +  }
  11473. +}
  11474. +
  11475. +
  11476. +/****************************************************************************
  11477. +  send a backup list response.
  11478. +  **************************************************************************/
  11479. +static void send_backup_list(char *work_name, struct nmb_name *src_name,
  11480. +                 int token, uint32 info,
  11481. +                 int name_type, struct in_addr ip)
  11482. +{                     
  11483. +  char outbuf[1024];
  11484. +  char *p, *countptr, *nameptr;
  11485. +  int count = 0;
  11486. +  char *theirname = src_name->name;
  11487. +  
  11488. +  DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n", 
  11489. +       work_name, inet_ntoa(ip),
  11490. +       myname,0x0,theirname,0x0));       
  11491. +  
  11492. +  if (name_type == 0x1d)
  11493. +    {
  11494. +      DEBUG(4,("master browsers: "));
  11495. +    }
  11496. +  else if (name_type == 0x1b)
  11497. +    {
  11498. +      DEBUG(4,("domain controllers: "));
  11499. +    }
  11500. +  else
  11501. +    {
  11502. +      DEBUG(0,("backup request for unknown type %0x\n", name_type));
  11503. +      return;
  11504. +    }
  11505. +  
  11506. +  bzero(outbuf,sizeof(outbuf));
  11507. +  p = outbuf;
  11508. +  
  11509. +  CVAL(p,0) = ANN_GetBackupListResp;    /* backup list response */
  11510. +  
  11511. +  p++;
  11512. +  countptr = p;
  11513. +
  11514. +  SIVAL(p,1,info); /* the sender's unique info */
  11515. +
  11516. +  p += 5;
  11517. +  
  11518. +  nameptr = p;
  11519. +
  11520. +#if 0
  11521. +
  11522. +  for (d = subnetlist; d; d = d->next)
  11523. +  {
  11524. +      struct work_record *work;
  11525. +      
  11526. +      for (work = d->workgrouplist; work; work = work->next)
  11527. +    {
  11528. +      struct server_record *s;
  11529. +      
  11530. +      if (!strequal(work->work_group, work_name)) continue;
  11531. +      
  11532. +      for (s = work->serverlist; s; s = s->next)
  11533. +        { 
  11534. +          BOOL found = False;
  11535. +          char *n;
  11536. +          
  11537. +          if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
  11538. +          
  11539. +          for (n = nameptr; n < p; n = skip_string(n, 1))
  11540. +        {
  11541. +          if (strequal(n, s->serv.name)) found = True;
  11542. +        }
  11543. +          
  11544. +          if (found) continue; /* exclude names already added */
  11545. +          
  11546. +          /* workgroup request: include all backup browsers in the list */
  11547. +          /* domain request: include all domain members in the list */
  11548. +
  11549. +          if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
  11550. +              (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
  11551. +        {                          
  11552. +          DEBUG(4, ("%s ", s->serv.name));
  11553. +          
  11554. +          count++;
  11555. +          strcpy(p,s->serv.name);
  11556. +          strupper(p);
  11557. +          p = skip_string(p,1);
  11558. +        }
  11559. +     }
  11560.      }
  11561. +  }
  11562. +
  11563. +#endif
  11564. +
  11565. +    count++;
  11566. +    strcpy(p,myname);
  11567. +    strupper(p);
  11568. +    p = skip_string(p,1);
  11569. +
  11570. +  if (count == 0)
  11571. +    {
  11572. +      DEBUG(4, ("none\n"));
  11573. +    }
  11574. +  else
  11575. +    {
  11576. +      DEBUG(4, (" - count %d\n", count));
  11577.      }
  11578. +  
  11579. +  CVAL(countptr, 0) = count;
  11580. +
  11581. +  {
  11582. +    int len = PTR_DIFF(p, outbuf);
  11583. +    debug_browse_data(outbuf, len);
  11584. +  }
  11585. +  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  11586. +              myname,theirname,0x0,0x0,ip,*iface_ip(ip));
  11587.  }
  11588.  
  11589. +
  11590.  /*******************************************************************
  11591.    process a send backup list request
  11592.  
  11593. -  A client send a backup list request to ask for a list of servers on
  11594. +  A client sends a backup list request to ask for a list of servers on
  11595.    the net that maintain server lists for a domain. A server is then
  11596.    chosen from this list to send NetServerEnum commands to to list
  11597.    available servers.
  11598. @@ -650,18 +535,15 @@
  11599.  {
  11600.    struct dgram_packet *dgram = &p->packet.dgram;
  11601.    struct in_addr ip = dgram->header.source_ip;
  11602. -  struct subnet_record *d; 
  11603. +  struct subnet_record *d;
  11604.    struct work_record *work;
  11605.  
  11606. -  int count = CVAL(buf,0);
  11607. -  int token = SVAL(buf,1); /* sender's key index for the workgroup? */
  11608. -  int info  = SVAL(buf,3); /* XXXX don't know: some sort of info */
  11609. +  int    token = CVAL(buf,0); /* sender's key index for the workgroup */
  11610. +  uint32 info  = IVAL(buf,1); /* XXXX don't know: some sort of info */
  11611.    int name_type = dgram->dest_name.name_type;
  11612.  
  11613.    if (same_context(dgram)) return;
  11614.    
  11615. -  if (count <= 0) return;
  11616. -  
  11617.    if (name_type != 0x1b && name_type != 0x1d) {
  11618.      DEBUG(0,("backup request to wrong type %d from %s\n",
  11619.            name_type,inet_ntoa(ip)));
  11620. @@ -674,11 +556,11 @@
  11621.      {
  11622.        if (strequal(work->work_group, dgram->dest_name.name))
  11623.          {
  11624. -          DEBUG(2,("sending backup list to %s %s count=%d\n",
  11625. -               namestr(&dgram->dest_name),inet_ntoa(ip),count));
  11626. +          DEBUG(2,("sending backup list to %s %s id=%x\n",
  11627. +               namestr(&dgram->dest_name),inet_ntoa(ip),info));
  11628.    
  11629.            send_backup_list(work->work_group,&dgram->source_name,
  11630. -                   count,token,info,name_type,ip);
  11631. +                   token,info,name_type,ip);
  11632.            return;
  11633.          }
  11634.      } 
  11635. @@ -690,7 +572,7 @@
  11636.    process a reset browser state
  11637.  
  11638.    diagnostic packet:
  11639. -  0x1 - stop being a master browser
  11640. +  0x1 - stop being a master browser and become a backup browser.
  11641.    0x2 - discard browse lists, stop being a master browser, try again.
  11642.    0x4 - stop being a master browser forever. no way. ain't gonna.
  11643.           
  11644. @@ -714,12 +596,16 @@
  11645.          {
  11646.            if (AM_MASTER(work))
  11647.          {
  11648. -          become_nonmaster(d,work);
  11649. +          become_nonmaster(d,work,SV_TYPE_DOMAIN_MASTER|SV_TYPE_MASTER_BROWSER);
  11650.          }
  11651.          }
  11652.      }
  11653.      }
  11654.    
  11655. +  /* XXXX documentation inconsistency: the above description does not
  11656. +     exactly tally with what is implemented for state & 0x2
  11657. +   */
  11658. +
  11659.    /* totally delete all servers and start afresh */
  11660.    if (state & 0x2)
  11661.      {
  11662. @@ -727,9 +613,9 @@
  11663.        for (d = subnetlist; d; d = d->next)
  11664.      {
  11665.        struct work_record *work;
  11666. -      for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
  11667. +      for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True));
  11668.      }
  11669. -      add_my_domains(lp_workgroup());
  11670. +      add_my_subnets(lp_workgroup());
  11671.      }
  11672.    
  11673.    /* stop browsing altogether. i don't think this is a good idea! */
  11674. @@ -739,7 +625,6 @@
  11675.      }
  11676.  }
  11677.  
  11678. -
  11679.  /*******************************************************************
  11680.    process a announcement request
  11681.  
  11682. @@ -751,7 +636,7 @@
  11683.    struct dgram_packet *dgram = &p->packet.dgram;
  11684.    struct work_record *work;
  11685.    struct in_addr ip = dgram->header.source_ip;
  11686. -  struct subnet_record *d = find_domain(ip);
  11687. +  struct subnet_record *d = find_subnet(ip);
  11688.    int token = CVAL(buf,0);
  11689.    char *name = buf+1;
  11690.    
  11691. @@ -762,12 +647,23 @@
  11692.    
  11693.    if (strequal(dgram->source_name.name,myname)) return;
  11694.    
  11695. +  /* XXXX BUG or FEATURE?: need to ensure that we are a member of
  11696. +     this workgroup before announcing, particularly as we only
  11697. +     respond on local interfaces anyway.
  11698. +
  11699. +     if (strequal(dgram->dest_name, lp_workgroup()) return; ???
  11700. +   */
  11701. +
  11702.    if (!d) return;
  11703.    
  11704.    if (!d->my_interface) return;
  11705.    
  11706.    for (work = d->workgrouplist; work; work = work->next)
  11707.      {
  11708. +     /* XXXX BUG: the destination name type should also be checked,
  11709. +        not just the name. e.g if the name is WORKGROUP(0x1d) then
  11710. +        we should only respond if we own that name */
  11711. +    
  11712.        if (strequal(dgram->dest_name.name,work->work_group)) 
  11713.      {
  11714.        work->needannounce = True;
  11715. @@ -777,89 +673,6 @@
  11716.  
  11717.  
  11718.  /****************************************************************************
  11719. -   process a domain logon packet
  11720. -   **************************************************************************/
  11721. -void process_logon_packet(struct packet_struct *p,char *buf,int len)
  11722. -{
  11723. -  struct dgram_packet *dgram = &p->packet.dgram;
  11724. -  struct in_addr ip = dgram->header.source_ip;
  11725. -  struct subnet_record *d = find_domain(ip);
  11726. -  char *logname,*q;
  11727. -  char *reply_name;
  11728. -  BOOL add_slashes = False;
  11729. -  pstring outbuf;
  11730. -  int code,reply_code;
  11731. -  struct work_record *work;
  11732. -  
  11733. -  if (!d) return;
  11734. -  
  11735. -  if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False))) 
  11736. -    return;
  11737. -  
  11738. -  if (!lp_domain_logons()) {
  11739. -    DEBUG(3,("No domain logons\n"));
  11740. -    return;
  11741. -  }
  11742. -  if (!listening_name(work, &dgram->dest_name))
  11743. -    {
  11744. -      DEBUG(4,("Not listening to that domain\n"));
  11745. -      return;
  11746. -    }
  11747. -  
  11748. -  code = SVAL(buf,0);
  11749. -  switch (code) {
  11750. -  case 0:    
  11751. -    {
  11752. -      char *machine = buf+2;
  11753. -      char *user = skip_string(machine,1);
  11754. -      logname = skip_string(user,1);
  11755. -      reply_code = 6;
  11756. -      reply_name = myname;
  11757. -      add_slashes = True;
  11758. -      DEBUG(3,("Domain login request from %s(%s) user=%s\n",
  11759. -            machine,inet_ntoa(p->ip),user));
  11760. -    }
  11761. -    break;
  11762. -  case 7:    
  11763. -    {
  11764. -      char *machine = buf+2;
  11765. -      logname = skip_string(machine,1);
  11766. -      reply_code = 7;
  11767. -      reply_name = lp_domain_controller();
  11768. -      if (!*reply_name) {
  11769. -     DEBUG(3,("No domain controller configured\n"));
  11770. -     return;
  11771. -      }
  11772. -      DEBUG(3,("GETDC request from %s(%s)\n",
  11773. -            machine,inet_ntoa(p->ip)));
  11774. -    }
  11775. -    break;
  11776. -  default:
  11777. -    DEBUG(3,("Unknown domain request %d\n",code));
  11778. -    return;
  11779. -  }
  11780. -  
  11781. -  bzero(outbuf,sizeof(outbuf));
  11782. -  q = outbuf;
  11783. -  SSVAL(q,0,reply_code);
  11784. -  q += 2;
  11785. -  if (add_slashes) {
  11786. -    strcpy(q,"\\\\");
  11787. -    q += 2;
  11788. -  }
  11789. -  StrnCpy(q,reply_name,16);
  11790. -  strupper(q);
  11791. -  q = skip_string(q,1);
  11792. -  SSVAL(q,0,0xFFFF);
  11793. -  q += 2;
  11794. -  
  11795. -  send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
  11796. -               myname,&dgram->source_name.name[0],0x20,0,p->ip,
  11797. -              *iface_ip(p->ip));  
  11798. -}
  11799. -
  11800. -/****************************************************************************
  11801.  depending on what announce has been made, we are only going to
  11802.  accept certain types of name announce. XXXX untested code
  11803.  
  11804. @@ -936,6 +749,7 @@
  11805.      case ANN_DomainAnnouncement:
  11806.      case ANN_LocalMasterAnnouncement:
  11807.        {
  11808. +        debug_browse_data(buf, len);
  11809.      process_announce(p,command,buf+1);
  11810.      break;
  11811.        }
  11812. @@ -954,15 +768,17 @@
  11813.        
  11814.      case ANN_GetBackupListReq:
  11815.        {
  11816. +        debug_browse_data(buf, len);
  11817.      process_send_backup_list(p,buf+1);
  11818.      break;
  11819.        }
  11820.        
  11821.      case ANN_GetBackupListResp:
  11822. -      {
  11823. -    process_rcv_backup_list(p, buf+1);
  11824. -    break;
  11825. -      }
  11826. +    {
  11827. +        debug_browse_data(buf, len);
  11828. +        process_rcv_backup_list(p, buf+1);
  11829. +        break;
  11830. +    }
  11831.        
  11832.      case ANN_ResetBrowserState:
  11833.        {
  11834. @@ -986,45 +802,4 @@
  11835.      }
  11836.  }
  11837.  
  11838. -
  11839. -/****************************************************************************
  11840. -process udp 138 datagrams
  11841. -****************************************************************************/
  11842. -void process_dgram(struct packet_struct *p)
  11843. -{
  11844. -  char *buf;
  11845. -  char *buf2;
  11846. -  int len;
  11847. -  struct dgram_packet *dgram = &p->packet.dgram;
  11848. -
  11849. -  if (dgram->header.msg_type != 0x10 &&
  11850. -      dgram->header.msg_type != 0x11 &&
  11851. -      dgram->header.msg_type != 0x12) {
  11852. -    /* don't process error packets etc yet */
  11853. -    return;
  11854. -  }
  11855. -
  11856. -  buf = &dgram->data[0];
  11857. -  buf -= 4; /* XXXX for the pseudo tcp length - 
  11858. -           someday I need to get rid of this */
  11859. -
  11860. -  if (CVAL(buf,smb_com) != SMBtrans) return;
  11861. -
  11862. -  len = SVAL(buf,smb_vwv11);
  11863. -  buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
  11864. -
  11865. -  DEBUG(4,("datagram from %s to %s for %s of type %d len=%d\n",
  11866. -       namestr(&dgram->source_name),namestr(&dgram->dest_name),
  11867. -       smb_buf(buf),CVAL(buf2,0),len));
  11868. -
  11869. -  if (len <= 0) return;
  11870. -
  11871. -   if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE"))
  11872. -   {
  11873. -     process_browse_packet(p,buf2,len);
  11874. -   } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) {
  11875. -     process_logon_packet(p,buf2,len);
  11876. -   }
  11877. -}
  11878.  
  11879. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/namework.doc samba-1.9.16alpha11/source/namework.doc
  11880. --- samba-1.9.16alpha10/source/namework.doc    Thu Jan  1 10:00:00 1970
  11881. +++ samba-1.9.16alpha11/source/namework.doc    Sun Jul  7 22:35:58 1996
  11882. @@ -0,0 +1,287 @@
  11883. +
  11884. +the module namework.c deals with NetBIOS datagram packets, primarily.
  11885. +it deals with nmbd's workgroup browser side and the domain log in
  11886. +side. none of the functionality here has specification documents available.
  11887. +empirical observation of packet traces has been the order of the day,
  11888. +along with some guess-work.
  11889. +
  11890. +beware!
  11891. +
  11892. +the receipt of datagram packets for workgroup browsing are dealt with here.
  11893. +some of the functions listed here will call others outside of this
  11894. +module, or will activate functionality dealt with by other modules
  11895. +(namedb, nameannounce, nameelect, namelogon, and namebrowse).
  11896. +
  11897. +
  11898. +/*************************************************************************
  11899. +  process_browse_packet()
  11900. +  *************************************************************************/
  11901. +
  11902. +this function is responsible for further identifying which type of
  11903. +browser datagram packet has been received, and dealing with it
  11904. +accordingly. if the packet is not dealt with, then an error is
  11905. +logged along with the type of packet that has been received.
  11906. +
  11907. +if listening_type() was in use, then it would be used here.
  11908. +
  11909. +the types of packets received and dealt with are:
  11910. +
  11911. +- ANN_HostAnnouncement         
  11912. +- ANN_DomainAnnouncement      
  11913. +- ANN_LocalMasterAnnouncement 
  11914. +
  11915. +these are all identical in format and can all be processed by
  11916. +process_announce(). an announcement is received from a host
  11917. +(either a master browser telling us about itself, a server
  11918. +telling us about itself or a master browser telling us about
  11919. +a domain / workgroup)
  11920. +
  11921. +- ANN_AnnouncementRequest      
  11922. +
  11923. +these are sent by master browsers or by servers. it is a
  11924. +request to announce ourselves as appropriate by sending
  11925. +either a ANN_HostAnnouncement datagram or both an
  11926. +ANN_DomainAnnouncement and an ANN_LocalMasterAnnouncement
  11927. +if we are a master browser (but not both).
  11928. +
  11929. +- ANN_Election                 
  11930. +
  11931. +this is an election datagram. if samba has been configured
  11932. +as a domain master then it will also send out election
  11933. +datagrams. 
  11934. +
  11935. +- ANN_GetBackupListReq         
  11936. +
  11937. +this is a request from another server for us to send a
  11938. +backup list of all servers that we know about. we respond
  11939. +by sending a datagram ANN_GetBackupListResp. the protocol
  11940. +here is a little dicey.
  11941. +
  11942. +- ANN_GetBackupListResp       
  11943. +
  11944. +this is a response from another server that we have sent an
  11945. +ANN_GetBackupListReq to. the protocol is a little dicey.
  11946. +
  11947. +- ANN_BecomeBackup            
  11948. +
  11949. +this is a message sent by a primary domain controller to a
  11950. +potential master browser, indicating that it should become
  11951. +a backup master browser for the workgroup it is a member
  11952. +of. samba does not respond at present to such datagrams,
  11953. +and it also sends out such datagrams for the wrong reasons
  11954. +(this code has now been disabled until this is fixed).
  11955. +
  11956. +- ANN_ResetBrowserState       
  11957. +
  11958. +this datagram is sent by a primary domain controller (or
  11959. +anyone else, for that matter) for trouble-shooting purposes.
  11960. +it asks a browser to clear out its server lists, or to
  11961. +stop becoming a master browser altogether. NT/AS and
  11962. +samba do not implement this latter option.
  11963. +
  11964. +- ANN_MasterAnnouncement      
  11965. +
  11966. +this datagram is sent by a master browser to a primary domain
  11967. +controller. it is a way to ensure that master browsers are
  11968. +kept in sync with a primary domain controller across a wide
  11969. +area network. on receipt of an ANN_MasterAnnouncement we
  11970. +should sync browse lists with the sender.
  11971. +
  11972. +(i never got the hang of this one when i was experimenting.
  11973. +i forget exactly what it's for, and i never fully worked
  11974. +out how to coax a server to send it. :-)
  11975. +
  11976. +
  11977. +/*************************************************************************
  11978. +  listening_type()
  11979. +  *************************************************************************/
  11980. +
  11981. +
  11982. +a datagram packet is sent from one NetBIOS name of a specific type
  11983. +to another NetBIOS name of a specific type. certain types of
  11984. +datagrams are only expected from certain types of NetBIOS names.
  11985. +
  11986. +this function is intended to catch errors in the type of datagrams
  11987. +received from different NetBIOS names. it is currently incomplete
  11988. +due to lack of information on the types of names and the datagrams
  11989. +they send.
  11990. +
  11991. +
  11992. +/*************************************************************************
  11993. +  process_announce_request()
  11994. +  *************************************************************************/
  11995. +
  11996. +this function is responsible for dealing with announcement requests.
  11997. +if the type of name that the request is sent to matches our current
  11998. +status, then we should respond. otherwise, the datagram should be
  11999. +ignored.
  12000. +
  12001. +samba only responds on its local subnets.
  12002. +
  12003. +at present, just the name is checked to see if the packet is for us.
  12004. +what should be done is that if we own the name (e.g WORGROUP(0x1d)
  12005. +or WORKGROUP(0x1b) then we should respond, otherwise, ignore the
  12006. +datagram.
  12007. +
  12008. +if the name is for us, and we are a member of that workgroup, then
  12009. +samba should respond.
  12010. +note that samba does not respond immediately. this is to ensure that
  12011. +if the master browser for the workgroup that samba is a member of
  12012. +sends out a broadcast request announcement, that that master browser
  12013. +is not swamped with replies. it is therefore up to samba to reply
  12014. +at some random interval. hence, a flag is set indicating the need
  12015. +to announce later.
  12016. +
  12017. +
  12018. +/*************************************************************************
  12019. +  process_reset_browser()
  12020. +  *************************************************************************/
  12021. +
  12022. +this function is responsible for dealing with reset state datagrams.
  12023. +there are three kinds of diagnostic reset requests:
  12024. +
  12025. +- stop being a master browser
  12026. +- discard browse lists, stop being a master browser, and run for re-election
  12027. +- stop being a master browser forever.
  12028. +
  12029. +samba and windows nt do not implement the latter option.
  12030. +
  12031. +there appears to be a discrepancy between this description and the
  12032. +code actually implemented.
  12033. +
  12034. +
  12035. +/*************************************************************************
  12036. +  process_send_backup_list()
  12037. +  *************************************************************************/
  12038. +
  12039. +this function is part of samba's primary domain controller functionality.
  12040. +
  12041. +it is responsible for giving master browsers a list of other browsers
  12042. +that maintain backup lists of servers for that master browser's workgroup.
  12043. +
  12044. +it is also responsible for giving master browsers a list of primary domain
  12045. +controllers for that master browser's domain.
  12046. +
  12047. +a correct way to think of this function is that it is a 'request to
  12048. +send out a backup list for the requested workgroup or domain'.
  12049. +
  12050. +i have some suspicions and intuitions about this function and how it
  12051. +is to actually be used. there is no documentation on this, so it is a
  12052. +matter of experimenting until it's right.
  12053. +
  12054. +
  12055. +/*************************************************************************
  12056. +  send_backup_list()
  12057. +  *************************************************************************/
  12058. +
  12059. +this function is responsible for compiling a list of either master
  12060. +browsers and backup master browsers or primary domain controllers or
  12061. +backup domain controllers. samba constructs this list from its 
  12062. +workgroup / server database.
  12063. +
  12064. +the list is then sent to the host that requested it by sending an
  12065. +ANN_GetBackupListResp datagram to this host.
  12066. +
  12067. +
  12068. +/*************************************************************************
  12069. +  process_rcv_backup_list()
  12070. +  *************************************************************************/
  12071. +
  12072. +this function is implemented with a slightly over-kill algorithm.
  12073. +the correct functionality is to pick any three names at random from
  12074. +the list that is received from this datagram, and then at intervals
  12075. +contact _one_ of them for a list of browser, in order to update
  12076. +samba's browse list.
  12077. +
  12078. +samba contacts every single one of the backup browsers listed, through
  12079. +the use of a NAME_QUERY_SRV_CHK 'state'.
  12080. +
  12081. +
  12082. +/*************************************************************************
  12083. +  process_master_announce()
  12084. +  *************************************************************************/
  12085. +
  12086. +this function is responsible for synchronising browse lists with a
  12087. +master browser that contacts samba in its capacity as a primary
  12088. +domain controller.
  12089. +
  12090. +the function add_browser_entry() is used to add the server that
  12091. +contacts us to our list of browser to sync browse lists with at
  12092. +some point in the near future.
  12093. +
  12094. +
  12095. +/*************************************************************************
  12096. +  process_announce()
  12097. +  *************************************************************************/
  12098. +
  12099. +this function is responsible for dealing with the three types of
  12100. +announcement type datagrams that samba recognises. some appropriate
  12101. +type-checking is done on the name that the datagram is sent to.
  12102. +
  12103. +samba does not at present deal with LanManager announcements.
  12104. +
  12105. +these announcements are for updating the browse entry records.
  12106. +each browse entry has a time-to-live associated with it. each server
  12107. +must refresh its entry with all other servers by broadcasting
  12108. +Announcements. if it does not do so, then other servers will not
  12109. +know about that machine, and the records on each server of that
  12110. +other machine will die.
  12111. +
  12112. +if an ANN_DomainAnnouncement is received, then this will be from
  12113. +a master browser. only one machine on any given broadcast area (e.g
  12114. +a subnet) should be broadcasting such announcements. the information
  12115. +it contains tells other servers that there is a master browser for
  12116. +this workgroup. if another server thinks that it is also a master
  12117. +browser for the same workgroup, then it should stop being a master
  12118. +browser and force an election.
  12119. +
  12120. +if an ANN_LocalMasterAnnouncement is received, then a master browser
  12121. +is telling us that it exists. i am uncertain that anything else
  12122. +actually needs to be done with this, other than to shout 'hooray' and
  12123. +'thank you for informing me of this fact'.
  12124. +
  12125. +
  12126. +/*************************************************************************
  12127. +  listening_name()
  12128. +  *************************************************************************/
  12129. +
  12130. +this function is an over-simplified way of identifying whether we
  12131. +should be responding to a datagram that has been received.
  12132. +
  12133. +
  12134. +/*************************************************************************
  12135. +  same_context()
  12136. +  *************************************************************************/
  12137. +
  12138. +this function helps us to identify whether we should be responding to
  12139. +a datagram that has been received.
  12140. +
  12141. +
  12142. +/*************************************************************************
  12143. +  tell_become_backup()
  12144. +  *************************************************************************/
  12145. +
  12146. +this function is part of samba's primary domain controller capabilities.
  12147. +it is responsible for finding appropriate servers to tell to become a
  12148. +backup master browser for the domain that samba controls.
  12149. +
  12150. +other servers that contact samba asking for a list of backup browsers
  12151. +will then be given that server's name, and that server can expect to
  12152. +receive NetServerEnum requests for lists of servers and workgroups.
  12153. +
  12154. +this function must be updated before it is in a fit state to be used.
  12155. +it must properly check whether a server is prepared to become a backup
  12156. +browser before actually asking it to be one.
  12157. +
  12158. +
  12159. +/*************************************************************************
  12160. +  reset_server()
  12161. +  *************************************************************************/
  12162. +
  12163. +this function is responsible for issuing an ANN_ResetBrowserState to
  12164. +the specified server, asking it to reset its browser information.
  12165. +
  12166. +see process_reset_browser() for details on this function.
  12167. +
  12168. +
  12169. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nmbd.c samba-1.9.16alpha11/source/nmbd.c
  12170. --- samba-1.9.16alpha10/source/nmbd.c    Mon Jun 10 15:18:56 1996
  12171. +++ samba-1.9.16alpha11/source/nmbd.c    Thu Jul 18 20:53:16 1996
  12172. @@ -55,21 +55,24 @@
  12173.  
  12174.  
  12175.   /****************************************************************************
  12176. -catch a sigterm
  12177. -****************************************************************************/
  12178. +  catch a sigterm
  12179. +  ****************************************************************************/
  12180.  static int sig_term()
  12181.  {
  12182.    BlockSignals(True);
  12183.    
  12184.    DEBUG(0,("Got SIGTERM: going down...\n"));
  12185.    
  12186. +  /* write out wins.dat file if samba is a WINS server */
  12187.    dump_names();
  12188. -  reload_services(True);
  12189.    
  12190.    /* remove all samba names, with wins server if necessary. */
  12191.    remove_my_names();
  12192.    
  12193. +  /* announce all server entries as 0 time-to-live, 0 type */
  12194.    /* XXXX don't care if we never receive a response back... yet */
  12195. +  remove_my_servers();
  12196. +
  12197.    /* XXXX other things: if we are a master browser, force an election? */
  12198.    
  12199.    exit(0);
  12200. @@ -204,6 +207,7 @@
  12201.    }
  12202.  
  12203.    load_interfaces();
  12204. +  add_subnet_interfaces();
  12205.  
  12206.    return(ret);
  12207.  }
  12208. @@ -286,9 +290,13 @@
  12209.        ipmask = *iface_nmask(ipaddr);
  12210.  
  12211.      if (group) {
  12212. -      add_subnet_entry(ipaddr, ipmask, name, True);
  12213. +      add_subnet_entry(ipaddr, ipmask, name, True, True);
  12214.      } else {
  12215. -      add_netbios_entry(name,0x20,NB_ACTIVE,0,source,ipaddr,True);
  12216. +      struct subnet_record *d = find_subnet(ipaddr);
  12217. +      if (d)
  12218. +      {
  12219. +        add_netbios_entry(d,name,0x20,NB_ACTIVE,0,source,ipaddr,True,True);
  12220. +      }
  12221.      }
  12222.        }
  12223.      }
  12224. @@ -315,17 +323,20 @@
  12225.  
  12226.        announce_host();
  12227.  
  12228. -#if 0
  12229. -      /* what was this stuff supposed to do? It sent
  12230. +#if 1
  12231. +      /* XXXX what was this stuff supposed to do? It sent
  12232.       ANN_GetBackupListReq packets which I think should only be
  12233.       sent when trying to find out who to browse with */     
  12234. +
  12235.        announce_backup();
  12236.  #endif
  12237.  
  12238.        announce_master();
  12239.  
  12240. +      query_refresh_names();
  12241. +
  12242.        expire_names_and_servers();
  12243. -      expire_netbios_response_entries(t-10);
  12244. +      expire_netbios_response_entries();
  12245.        refresh_my_names(t);
  12246.  
  12247.        write_browse_list();
  12248. @@ -446,7 +457,7 @@
  12249.  
  12250.    fault_setup(fault_continue);
  12251.  
  12252. -  signal(SIGHUP,SIGNAL_CAST sig_hup);
  12253. +  signal(SIGHUP ,SIGNAL_CAST sig_hup);
  12254.    signal(SIGTERM,SIGNAL_CAST sig_term);
  12255.  
  12256.    while ((opt = getopt(argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
  12257. @@ -514,7 +525,7 @@
  12258.      return(-1);    
  12259.  
  12260.    if (*group)
  12261. -    add_my_domains(group);
  12262. +    add_my_subnets(group);
  12263.  
  12264.    if (!is_daemon && !is_a_socket(0)) {
  12265.      DEBUG(0,("standard input is not a socket, assuming -D option\n"));
  12266. @@ -535,16 +546,22 @@
  12267.      DEBUG(3,("Loaded hosts file\n"));
  12268.    }
  12269.  
  12270. +
  12271. +
  12272.    if (!*ServerComment)
  12273.      strcpy(ServerComment,"Samba %v");
  12274.    string_sub(ServerComment,"%v",VERSION);
  12275.    string_sub(ServerComment,"%h",myhostname);
  12276.  
  12277.    add_my_names();
  12278. -  add_my_domains(lp_workgroup());
  12279. +  add_my_subnets(lp_workgroup());
  12280.  
  12281.    DEBUG(3,("Checked names\n"));
  12282.    
  12283. +  load_netbios_names();
  12284. +
  12285. +  DEBUG(3,("Loaded names\n"));
  12286. +
  12287.    write_browse_list();
  12288.  
  12289.    DEBUG(3,("Dumped names\n"));
  12290. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nmblookup.c samba-1.9.16alpha11/source/nmblookup.c
  12291. --- samba-1.9.16alpha10/source/nmblookup.c    Sat Jun  8 15:37:54 1996
  12292. +++ samba-1.9.16alpha11/source/nmblookup.c    Thu Jul 18 20:53:16 1996
  12293. @@ -49,7 +49,7 @@
  12294.        return False;
  12295.      }   
  12296.  
  12297. -  ServerFD = open_socket_in(SOCK_DGRAM, 0,3);
  12298. +  ServerFD = open_socket_in(SOCK_DGRAM, NMB_PORT,3);
  12299.  
  12300.    if (ServerFD == -1)
  12301.      return(False);
  12302. @@ -93,7 +93,7 @@
  12303.  int main(int argc,char *argv[])
  12304.  {
  12305.    int opt;
  12306. -  unsigned int lookup_type = 0;
  12307. +  unsigned int lookup_type = 0x0;
  12308.    pstring lookup;
  12309.    extern int optind;
  12310.    extern char *optarg;
  12311. @@ -164,7 +164,7 @@
  12312.        strcpy(lookup,"\01\02__MSBROWSE__\02");
  12313.        lookup_type = 1;
  12314.      } else {
  12315. -      lookup_type = 0x1d;
  12316. +      lookup_type = 0x1b;
  12317.      }
  12318.        }
  12319.  
  12320. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/nmbsync.c samba-1.9.16alpha11/source/nmbsync.c
  12321. --- samba-1.9.16alpha10/source/nmbsync.c    Mon Jun 10 15:18:57 1996
  12322. +++ samba-1.9.16alpha11/source/nmbsync.c    Mon Jul 15 17:55:05 1996
  12323. @@ -102,6 +102,7 @@
  12324.            uint32 stype = IVAL(p,18);
  12325.            int comment_offset = IVAL(p,22) & 0xFFFF;
  12326.            char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
  12327. +          
  12328.            struct work_record *w = work;
  12329.            
  12330.            DEBUG(4, ("\t%-16.16s     %08x    %s\n", sname, stype, cmnt));
  12331. @@ -109,17 +110,17 @@
  12332.            if (stype & SV_TYPE_DOMAIN_ENUM)
  12333.          {
  12334.            /* creates workgroup on remote subnet */
  12335. -          if ((w = find_workgroupstruct(d,sname, True)))
  12336. +          if ((w = find_workgroupstruct(d,sname,True)))
  12337.              {
  12338.                if (d->my_interface)
  12339.              {
  12340.                announce_request(w, d->bcast_ip);
  12341.              }
  12342.              }
  12343. -        }          
  12344. +        }
  12345.            
  12346. -          if (w)
  12347. -        add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
  12348. +          if (w)
  12349. +            add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
  12350.          }
  12351.      }
  12352.      }
  12353. @@ -137,10 +138,11 @@
  12354.    log in on the remote server's SMB port to their IPC$ service,
  12355.    do a NetServerEnum and update our server and workgroup databases.
  12356.    ******************************************************************/
  12357. -void sync_browse_lists(struct work_record *work, char *name, int nm_type,
  12358. -               struct in_addr ip)
  12359. +void sync_browse_lists(struct subnet_record *d, struct work_record *work,
  12360. +        char *name, int nm_type, struct in_addr ip)
  12361.  {
  12362. -  struct subnet_record *d;
  12363. +  if (!d || !work || !AM_MASTER(work)) return;
  12364. +
  12365.    pid = getpid();
  12366.    uid = getuid();
  12367.    gid = getgid();
  12368. @@ -158,8 +160,6 @@
  12369.    
  12370.    if (zero_ip(dest_ip)) return;
  12371.    have_ip = True;
  12372. -  
  12373. -  if (!(d = find_domain(ip))) return;
  12374.    
  12375.    connect_as_ipc = True;
  12376.    
  12377. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/printing.c samba-1.9.16alpha11/source/printing.c
  12378. --- samba-1.9.16alpha10/source/printing.c    Mon Jun 10 15:18:59 1996
  12379. +++ samba-1.9.16alpha11/source/printing.c    Sun Jun 30 15:17:26 1996
  12380. @@ -600,10 +600,19 @@
  12381.  /****************************************************************************
  12382.    parse a lpq line for the plp printing system
  12383.    Bertrand Wallrich <Bertrand.Wallrich@loria.fr>
  12384. +
  12385. +redone by tridge. Here is a sample queue:
  12386. +
  12387. +Local  Printer 'lp2' (fjall):
  12388. +  Printing (started at Jun 15 13:33:58, attempt 1).
  12389. +    Rank Owner       Pr Opt  Job Host        Files           Size     Date
  12390. +  active tridge      X  -    6   fjall       /etc/hosts      739      Jun 15 13:33
  12391. +     3rd tridge      X  -    7   fjall       /etc/hosts      739      Jun 15 13:33
  12392. +
  12393.  ****************************************************************************/
  12394.  static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
  12395.  {
  12396. -  string tok[5];
  12397. +  string tok[11];
  12398.    int count=0;
  12399.  
  12400.    /* handle the case of "(standard input)" as a filename */
  12401. @@ -611,60 +620,49 @@
  12402.    string_sub(line,"(","\"");
  12403.    string_sub(line,")","\"");
  12404.    
  12405. -  for (count=0; count<8 && next_token(&line,tok[count],NULL); count++) ;
  12406. +  for (count=0; count<11 && next_token(&line,tok[count],NULL); count++) ;
  12407. +
  12408. +  /* we must get 11 tokens */
  12409. +  if (count < 11)
  12410. +    return(False);
  12411.  
  12412. -  /* we must get 5 tokens */
  12413. -  if (count < 8)
  12414. +  /* the first must be "active" or begin with an integer */
  12415. +  if (strcmp(tok[0],"active") && !isdigit(tok[0][0]))
  12416.      return(False);
  12417.  
  12418. -  /* the 4rd must be integer */
  12419. -  if (!isdigit(*tok[3])) return(False);
  12420. +  /* the 5th and 8th must be integer */
  12421. +  if (!isdigit(*tok[4]) || !isdigit(*tok[7])) 
  12422. +    return(False);
  12423.  
  12424.    /* if the fname contains a space then use STDIN */
  12425. -  if (strchr(tok[3],' '))
  12426. -    strcpy(tok[3],"STDIN");
  12427. +  if (strchr(tok[6],' '))
  12428. +    strcpy(tok[6],"STDIN");
  12429.  
  12430.    /* only take the last part of the filename */
  12431.    {
  12432.      string tmp;
  12433. -    char *p = strrchr(tok[5],'/');
  12434. +    char *p = strrchr(tok[6],'/');
  12435.      if (p)
  12436.        {
  12437.          strcpy(tmp,p+1);
  12438. -        strcpy(tok[5],tmp);
  12439. +        strcpy(tok[6],tmp);
  12440.        }
  12441.    }
  12442.  
  12443.  
  12444. -  buf->job = atoi(tok[3]);
  12445. +  buf->job = atoi(tok[4]);
  12446.  
  12447. -  /* calcul de la taille du fichier */
  12448. -  if (!isdigit(*tok[7])) {  buf->size = atoi(tok[7]) * 1.0 ; }
  12449. -  else {
  12450. -    string tmp;
  12451. -    strcpy(tmp,tok[7]);
  12452. -    if (strchr(tok[7],'K')) {
  12453. -      strncpy(tok[7],tmp,strlen(tmp)-1);
  12454. -      buf->size = atoi(tok[7]);
  12455. -      buf->size = buf->size * 1024;
  12456. -    }
  12457. -    if (strchr(tok[7],'M')) {
  12458. -      strncpy(tok[7],tmp,strlen(tmp)-1);
  12459. -      buf->size = atoi(tok[7]);
  12460. -      buf->size = buf->size * 1024.0 * 1000.0;
  12461. -    }
  12462. -    if (strchr(tok[7],'G')) {
  12463. -      strncpy(tok[7],tmp,strlen(tmp)-1);
  12464. -      buf->size = atoi(tok[7]);
  12465. -      buf->size = buf->size * 1024.0 * 1000000.0;
  12466. -    }
  12467. +  buf->size = atoi(tok[7]);
  12468. +  if (strchr(tok[7],'K'))
  12469. +    buf->size *= 1024;
  12470. +  if (strchr(tok[7],'M'))
  12471. +    buf->size *= 1024*1024;
  12472.  
  12473. -  }
  12474.    buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
  12475.    buf->priority = 0;
  12476.    buf->time = time(NULL);
  12477.    StrnCpy(buf->user,tok[1],sizeof(buf->user)-1);
  12478. -  StrnCpy(buf->file,tok[5],sizeof(buf->file)-1);
  12479. +  StrnCpy(buf->file,tok[6],sizeof(buf->file)-1);
  12480.    return(True);
  12481.  }
  12482.  
  12483. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/proto.h samba-1.9.16alpha11/source/proto.h
  12484. --- samba-1.9.16alpha10/source/proto.h    Mon Jun 10 15:18:59 1996
  12485. +++ samba-1.9.16alpha11/source/proto.h    Thu Jul 18 20:53:16 1996
  12486. @@ -1,20 +1,39 @@
  12487.  /* This file is automatically generated with "make proto". DO NOT EDIT */
  12488. +
  12489. +
  12490. +/*The following definitions come from  access.c  */
  12491. +
  12492.  BOOL check_access(int snum);
  12493.  BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
  12494.  BOOL fromhost(int sock,struct from_host *f);
  12495. +
  12496. +/*The following definitions come from  charcnv.c  */
  12497. +
  12498.  char *unix2dos_format(char *str,BOOL overwrite);
  12499.  char *dos2unix_format(char *str, BOOL overwrite);
  12500.  int interpret_character_set(char *str, int def);
  12501. +
  12502. +/*The following definitions come from  charset.c  */
  12503. +
  12504.  void charset_initialise(void);
  12505.  void add_char_string(char *s);
  12506. +
  12507. +/*The following definitions come from  chgpasswd.c  */
  12508. +
  12509.  BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence);
  12510.  BOOL chgpasswd(char *name,char *oldpass,char *newpass);
  12511.  BOOL chgpasswd(char *name,char *oldpass,char *newpass);
  12512. +
  12513. +/*The following definitions come from  client.c  */
  12514. +
  12515.  void setup_pkt(char *outbuf);
  12516.  void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
  12517.  void cmd_help(void);
  12518.  BOOL reopen_connection(char *inbuf,char *outbuf);
  12519.  char *smb_errstr(char *inbuf);
  12520. +
  12521. +/*The following definitions come from  clientutil.c  */
  12522. +
  12523.  void cli_setup_pkt(char *outbuf);
  12524.  BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
  12525.                  int *param_len, char **data,char **param);
  12526. @@ -29,6 +48,9 @@
  12527.  BOOL cli_open_sockets(int port);
  12528.  BOOL cli_reopen_connection(char *inbuf,char *outbuf);
  12529.  char *smb_errstr(char *inbuf);
  12530. +
  12531. +/*The following definitions come from  clitar.c  */
  12532. +
  12533.  int strslashcmp(const char *s1, const char *s2);
  12534.  void cmd_block(void);
  12535.  void cmd_tarmode(void);
  12536. @@ -37,6 +59,9 @@
  12537.  int process_tar(char *inbuf, char *outbuf);
  12538.  int clipfind(char **aret, int ret, char *tok);
  12539.  int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
  12540. +
  12541. +/*The following definitions come from  dir.c  */
  12542. +
  12543.  void init_dptrs(void);
  12544.  char *dptr_path(int key);
  12545.  char *dptr_wcard(int key);
  12546. @@ -62,8 +87,17 @@
  12547.  void DirCacheAdd(char *path,char *name,char *dname,int snum);
  12548.  char *DirCacheCheck(char *path,char *name,int snum);
  12549.  void DirCacheFlush(int snum);
  12550. +
  12551. +/*The following definitions come from  fault.c  */
  12552. +
  12553.  void fault_setup(void (*fn)());
  12554. +
  12555. +/*The following definitions come from  getsmbpass.c  */
  12556. +
  12557.  char *getsmbpass(char *prompt)    ;
  12558. +
  12559. +/*The following definitions come from  interface.c  */
  12560. +
  12561.  void load_interfaces(void);
  12562.  void iface_set_default(char *ip,char *bcast,char *nmask);
  12563.  BOOL ismyip(struct in_addr ip);
  12564. @@ -73,8 +107,17 @@
  12565.  struct in_addr *iface_bcast(struct in_addr ip);
  12566.  struct in_addr *iface_nmask(struct in_addr ip);
  12567.  struct in_addr *iface_ip(struct in_addr ip);
  12568. +
  12569. +/*The following definitions come from  ipc.c  */
  12570. +
  12571.  int reply_trans(char *inbuf,char *outbuf);
  12572. +
  12573. +/*The following definitions come from  kanji.c  */
  12574. +
  12575.  int interpret_coding_system(char *str, int def);
  12576. +
  12577. +/*The following definitions come from  loadparm.c  */
  12578. +
  12579.  char *lp_string(char *s);
  12580.  char *lp_logfile(void);
  12581.  char *lp_smbrun(void);
  12582. @@ -99,6 +142,7 @@
  12583.  char *lp_logon_script(void);
  12584.  char *lp_wins_server(void);
  12585.  char *lp_interfaces(void);
  12586. +char *lp_remote_interfaces(void);
  12587.  BOOL lp_wins_support(void);
  12588.  BOOL lp_wins_proxy(void);
  12589.  BOOL lp_domain_master(void);
  12590. @@ -206,6 +250,9 @@
  12591.  int lp_servicenumber(char *pszServiceName);
  12592.  char *my_workgroup(void);
  12593.  char *volume_label(int snum);
  12594. +
  12595. +/*The following definitions come from  locking.c  */
  12596. +
  12597.  BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
  12598.  int file_lock(char *name,int timeout);
  12599.  void file_unlock(int fd);
  12600. @@ -218,6 +265,9 @@
  12601.  void del_share_mode(int fnum);
  12602.  BOOL set_share_mode(int fnum,int mode);
  12603.  void clean_share_files(void);
  12604. +
  12605. +/*The following definitions come from  mangle.c  */
  12606. +
  12607.  int str_checksum(char *s);
  12608.  BOOL is_8_3(char *fname);
  12609.  void create_mangled_stack(int size);
  12610. @@ -225,109 +275,217 @@
  12611.  BOOL is_mangled(char *s);
  12612.  void mangle_name_83(char *s);
  12613.  BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
  12614. +
  12615. +/*The following definitions come from  md4.c  */
  12616. +
  12617. +
  12618. +/*The following definitions come from  message.c  */
  12619. +
  12620.  int reply_sends(char *inbuf,char *outbuf);
  12621.  int reply_sendstrt(char *inbuf,char *outbuf);
  12622.  int reply_sendtxt(char *inbuf,char *outbuf);
  12623.  int reply_sendend(char *inbuf,char *outbuf);
  12624. +
  12625. +/*The following definitions come from  nameannounce.c  */
  12626. +
  12627.  void announce_request(struct work_record *work, struct in_addr ip);
  12628.  void do_announce_request(char *info, char *to_name, int announce_type, 
  12629.               int from,
  12630.               int to, struct in_addr dest_ip);
  12631. +void sync_server(enum state_type state, char *serv_name, char *work_name, 
  12632. +         int name_type,
  12633. +         struct in_addr ip);
  12634.  void announce_backup(void);
  12635. +void remove_my_servers(void);
  12636. +void announce_server(struct subnet_record *d, struct work_record *work,
  12637. +                    char *name, char *comment, time_t ttl, int server_type);
  12638.  void announce_host(void);
  12639.  void announce_master(void);
  12640. -struct work_record *remove_workgroup(struct subnet_record *d, 
  12641. -                     struct work_record *work);
  12642. +
  12643. +/*The following definitions come from  namebrowse.c  */
  12644. +
  12645.  void expire_browse_cache(time_t t);
  12646. -struct work_record *find_workgroupstruct(struct subnet_record *d, 
  12647. -                     fstring name, BOOL add);
  12648. -struct subnet_record *find_domain(struct in_addr ip);
  12649. -void dump_workgroups(void);
  12650. -struct subnet_record *add_subnet_entry(struct in_addr source_ip, 
  12651. -                       struct in_addr source_mask,
  12652. -                       char *name, BOOL add);
  12653.  struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
  12654.                            time_t ttl, struct in_addr ip);
  12655. +void do_browser_lists(void);
  12656. +
  12657. +/*The following definitions come from  namedbname.c  */
  12658. +
  12659. +BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2);
  12660. +BOOL ms_browser_name(char *name, int type);
  12661. +void remove_name(struct subnet_record *d, struct name_record *n);
  12662. +struct name_record *find_name(struct name_record *n,
  12663. +            struct nmb_name *name,
  12664. +            int search);
  12665. +struct name_record *find_name_search(struct subnet_record **d,
  12666. +            struct nmb_name *name,
  12667. +            int search, struct in_addr ip);
  12668. +void dump_names(void);
  12669. +void load_netbios_names(void);
  12670. +void remove_netbios_name(struct subnet_record *d,
  12671. +            char *name,int type, enum name_source source,
  12672. +             struct in_addr ip);
  12673. +struct name_record *add_netbios_entry(struct subnet_record *d,
  12674. +        char *name, int type, int nb_flags, 
  12675. +        int ttl, enum name_source source, struct in_addr ip,
  12676. +        BOOL new_only,BOOL wins);
  12677. +void expire_names(time_t t);
  12678. +struct name_record *search_for_name(struct subnet_record **d,
  12679. +                    struct nmb_name *question,
  12680. +                    struct in_addr ip, int Time, int search);
  12681. +
  12682. +/*The following definitions come from  namedbresp.c  */
  12683. +
  12684. +void add_response_record(struct subnet_record *d,
  12685. +                struct response_record *n);
  12686. +void remove_response_record(struct subnet_record *d,
  12687. +                struct response_record *n);
  12688. +struct response_record *make_response_queue_record(enum state_type state,
  12689. +                int id,uint16 fd,
  12690. +                int quest_type, char *name,int type, int nb_flags, time_t ttl,
  12691. +                BOOL bcast,BOOL recurse,
  12692. +                struct in_addr send_ip, struct in_addr reply_to_ip);
  12693. +struct response_record *find_response_record(struct subnet_record **d,
  12694. +                uint16 id);
  12695. +
  12696. +/*The following definitions come from  namedbserver.c  */
  12697. +
  12698. +void remove_old_servers(struct work_record *work, time_t t,
  12699. +                    BOOL remove_all);
  12700. +struct server_record *find_server(struct work_record *work, char *name);
  12701.  struct server_record *add_server_entry(struct subnet_record *d, 
  12702.                         struct work_record *work,
  12703.                         char *name,int servertype, 
  12704.                         int ttl,char *comment,
  12705.                         BOOL replace);
  12706. -void write_browse_list(void);
  12707.  void expire_servers(time_t t);
  12708. +
  12709. +/*The following definitions come from  namedbsubnet.c  */
  12710. +
  12711. +struct subnet_record *find_subnet(struct in_addr bcast_ip);
  12712. +struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast);
  12713. +void add_subnet_interfaces(void);
  12714. +void add_my_subnets(char *group);
  12715. +struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, 
  12716. +                       struct in_addr mask_ip,
  12717. +                       char *name, BOOL add, BOOL lmhosts);
  12718. +void write_browse_list(void);
  12719. +
  12720. +/*The following definitions come from  namedbwork.c  */
  12721. +
  12722. +struct work_record *remove_workgroup(struct subnet_record *d, 
  12723. +                     struct work_record *work,
  12724. +                     BOOL remove_all_servers);
  12725. +struct work_record *find_workgroupstruct(struct subnet_record *d, 
  12726. +                     fstring name, BOOL add);
  12727. +void dump_workgroups(void);
  12728. +
  12729. +/*The following definitions come from  nameelect.c  */
  12730. +
  12731.  void check_master_browser(void);
  12732.  void browser_gone(char *work_name, struct in_addr ip);
  12733.  void send_election(struct subnet_record *d, char *group,uint32 criterion,
  12734.             int timeup,char *name);
  12735. -void become_nonmaster(struct subnet_record *d, struct work_record *work);
  12736. +void name_unregister_work(struct subnet_record *d, char *name, int name_type);
  12737. +void name_register_work(struct subnet_record *d, char *name, int name_type,
  12738. +                int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast);
  12739. +void become_master(struct subnet_record *d, struct work_record *work);
  12740. +void become_nonmaster(struct subnet_record *d, struct work_record *work,
  12741. +                int remove_type);
  12742.  void run_elections(void);
  12743.  void process_election(struct packet_struct *p,char *buf);
  12744.  BOOL check_elections(void);
  12745. -BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
  12746. -         struct in_addr to_ip,char *master,char *rname,
  12747. -         void (*fn)());
  12748. -BOOL name_query(int fd,char *name,int name_type, 
  12749. -        BOOL bcast,BOOL recurse,
  12750. -        struct in_addr to_ip, struct in_addr *ip,void (*fn)());
  12751. -void expire_netbios_response_entries(time_t t);
  12752. -void reply_netbios_packet(struct packet_struct *p1,int trn_id,int rcode,
  12753. -              int opcode,BOOL recurse,struct nmb_name *rr_name,
  12754. -              int rr_type,int rr_class,int ttl,char *data,int len);
  12755. -uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type,
  12756. -                   int nb_flags,BOOL bcast,BOOL recurse,
  12757. -                   struct in_addr to_ip);
  12758. -void queue_netbios_pkt_wins(int fd,int quest_type,enum cmd_type cmd,
  12759. -                char *name,int name_type,int nb_flags,
  12760. -                BOOL bcast,BOOL recurse,struct in_addr to_ip);
  12761. -void queue_netbios_packet(int fd,int quest_type,enum cmd_type cmd,char *name,
  12762. -              int name_type,int nb_flags,BOOL bcast,BOOL recurse,
  12763. -              struct in_addr to_ip);
  12764. -struct name_response_record *find_name_query(uint16 id);
  12765. +
  12766. +/*The following definitions come from  namelogon.c  */
  12767. +
  12768. +void process_logon_packet(struct packet_struct *p,char *buf,int len);
  12769. +
  12770. +/*The following definitions come from  namepacket.c  */
  12771. +
  12772. +void debug_browse_data(char *outbuf, int len);
  12773. +void initiate_netbios_packet(uint16 *id,
  12774. +                int fd,int quest_type,char *name,int name_type,
  12775. +                int nb_flags,BOOL bcast,BOOL recurse,
  12776. +                struct in_addr to_ip);
  12777. +void reply_netbios_packet(struct packet_struct *p1,int trn_id,
  12778. +                int rcode, int rcv_code, int opcode, BOOL recurse,
  12779. +                struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
  12780. +                char *data,int len);
  12781.  void queue_packet(struct packet_struct *packet);
  12782.  void run_packet_queue();
  12783.  void listen_for_packets(BOOL run_election);
  12784. -BOOL interpret_node_status(char *p, struct nmb_name *name,int t,
  12785. -               char *serv_name, struct in_addr ip);
  12786.  BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
  12787.               char *dstname,int src_type,int dest_type,
  12788.               struct in_addr dest_ip,struct in_addr src_ip);
  12789. -void remove_name(struct name_record *n);
  12790. -void dump_names(void);
  12791. -void remove_netbios_name(char *name,int type, enum name_source source,
  12792. -             struct in_addr ip);
  12793. -struct name_record *add_netbios_entry(char *name, int type, int nb_flags, 
  12794. -                      int ttl,
  12795. -                      enum name_source source, 
  12796. -                      struct in_addr ip,
  12797. -                      BOOL new_only);
  12798. -void remove_name_entry(char *name,int type);
  12799. -void add_name_entry(char *name,int type,int nb_flags);
  12800. +
  12801. +/*The following definitions come from  namequery.c  */
  12802. +
  12803. +BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
  12804. +         struct in_addr to_ip,char *master,char *rname,
  12805. +         void (*fn)());
  12806. +BOOL name_query(int fd,char *name,int name_type, 
  12807. +        BOOL bcast,BOOL recurse,
  12808. +        struct in_addr to_ip, struct in_addr *ip,void (*fn)());
  12809. +
  12810. +/*The following definitions come from  nameresp.c  */
  12811. +
  12812. +void expire_netbios_response_entries();
  12813. +struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
  12814. +                int fd,int quest_type,enum state_type state,
  12815. +                char *name,int name_type,int nb_flags, time_t ttl,
  12816. +                BOOL bcast,BOOL recurse,
  12817. +                struct in_addr send_ip, struct in_addr reply_to_ip);
  12818. +struct response_record *queue_netbios_packet(struct subnet_record *d,
  12819. +            int fd,int quest_type,enum state_type state,char *name,
  12820. +            int name_type,int nb_flags, time_t ttl,
  12821. +                BOOL bcast,BOOL recurse,
  12822. +                struct in_addr send_ip, struct in_addr reply_to_ip);
  12823. +
  12824. +/*The following definitions come from  nameserv.c  */
  12825. +
  12826. +void remove_name_entry(struct subnet_record *d, char *name,int type);
  12827. +void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags);
  12828.  void add_my_names(void);
  12829.  void remove_my_names();
  12830.  void refresh_my_names(time_t t);
  12831. -void expire_names(time_t t);
  12832. -void response_name_release(struct packet_struct *p);
  12833. +void query_refresh_names(void);
  12834. +
  12835. +/*The following definitions come from  nameservreply.c  */
  12836. +
  12837. +void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
  12838. +                uint16 response_id,
  12839. +                struct nmb_name *name,
  12840. +                int nb_flags, int ttl, struct in_addr register_ip,
  12841. +                BOOL new_owner, struct in_addr reply_to_ip);
  12842. +void send_name_response(int fd, struct in_addr from_ip,
  12843. +                int name_trn_id, int opcode, BOOL success, BOOL recurse,
  12844. +                struct nmb_name *reply_name, int nb_flags, int ttl,
  12845. +                struct in_addr ip);
  12846.  void reply_name_release(struct packet_struct *p);
  12847. -void response_name_reg(struct packet_struct *p);
  12848.  void reply_name_reg(struct packet_struct *p);
  12849.  void reply_name_status(struct packet_struct *p);
  12850.  void reply_name_query(struct packet_struct *p);
  12851. -void process_nmb(struct packet_struct *p);
  12852. +
  12853. +/*The following definitions come from  nameservresp.c  */
  12854. +
  12855. +void debug_state_type(int state);
  12856. +void response_netbios_packet(struct packet_struct *p);
  12857. +
  12858. +/*The following definitions come from  namework.c  */
  12859. +
  12860.  void reset_server(char *name, int state, struct in_addr ip);
  12861.  void tell_become_backup(void);
  12862. -void do_browser_lists(void);
  12863. -void sync_server(enum cmd_type cmd, char *serv_name, char *work_name, 
  12864. -         int name_type,
  12865. -         struct in_addr ip);
  12866. -void update_from_reg(char *name, int type, struct in_addr ip);
  12867. -void add_my_domains(char *group);
  12868.  BOOL same_context(struct dgram_packet *dgram);
  12869.  BOOL listening_name(struct work_record *work, struct nmb_name *n);
  12870. -void process_logon_packet(struct packet_struct *p,char *buf,int len);
  12871.  BOOL listening_type(struct packet_struct *p, int command);
  12872.  void process_browse_packet(struct packet_struct *p,char *buf,int len);
  12873. -void process_dgram(struct packet_struct *p);
  12874. +
  12875. +/*The following definitions come from  nmbd.c  */
  12876. +
  12877.  BOOL reload_services(BOOL test);
  12878. +
  12879. +/*The following definitions come from  nmblib.c  */
  12880. +
  12881.  void debug_nmb_packet(struct packet_struct *p);
  12882.  char *namestr(struct nmb_name *n);
  12883.  void free_nmb_packet(struct nmb_packet *nmb);
  12884. @@ -336,11 +494,23 @@
  12885.  void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
  12886.  BOOL send_packet(struct packet_struct *p);
  12887.  struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
  12888. +
  12889. +/*The following definitions come from  nmblookup.c  */
  12890. +
  12891.  int main(int argc,char *argv[]);
  12892. +
  12893. +/*The following definitions come from  nmbsync.c  */
  12894. +
  12895.  char *getsmbpass(char *pass);
  12896. -void sync_browse_lists(struct work_record *work, char *name, int nm_type,
  12897. -               struct in_addr ip);
  12898. +void sync_browse_lists(struct subnet_record *d, struct work_record *work,
  12899. +        char *name, int nm_type, struct in_addr ip);
  12900. +
  12901. +/*The following definitions come from  params.c  */
  12902. +
  12903.  BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *));
  12904. +
  12905. +/*The following definitions come from  password.c  */
  12906. +
  12907.  void generate_next_challenge(char *challenge);
  12908.  BOOL set_challenge(char *challenge);
  12909.  BOOL last_challenge(char *challenge);
  12910. @@ -360,21 +530,36 @@
  12911.  BOOL check_hosts_equiv(char *user);
  12912.  BOOL server_cryptkey(char *buf);
  12913.  BOOL server_validate(char *buf);
  12914. +
  12915. +/*The following definitions come from  pcap.c  */
  12916. +
  12917.  BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
  12918.  void pcap_printer_fn(void (*fn)());
  12919. +
  12920. +/*The following definitions come from  predict.c  */
  12921. +
  12922.  int read_predict(int fd,int offset,char *buf,char **ptr,int num);
  12923.  void do_read_prediction();
  12924.  void invalidate_read_prediction(int fd);
  12925. +
  12926. +/*The following definitions come from  printing.c  */
  12927. +
  12928.  void lpq_reset(int snum);
  12929.  void print_file(int fnum);
  12930.  int get_printqueue(int snum,int cnum,print_queue_struct **queue,
  12931.             print_status_struct *status);
  12932.  void del_printqueue(int cnum,int snum,int jobid);
  12933.  void status_printjob(int cnum,int snum,int jobid,int status);
  12934. +
  12935. +/*The following definitions come from  quotas.c  */
  12936. +
  12937.  BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
  12938.  BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
  12939.  BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
  12940.  BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
  12941. +
  12942. +/*The following definitions come from  replace.c  */
  12943. +
  12944.  char *Strstr(char *s, char *p);
  12945.  time_t Mktime(struct tm      *t);
  12946.  int InNetGr(char *group,char *host,char *user,char *dom);
  12947. @@ -382,6 +567,9 @@
  12948.  void *realloc_wrapped(void *ptr,int size,char *file,int line);
  12949.  void free_wrapped(void *ptr,char *file,int line);
  12950.  void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line);
  12951. +
  12952. +/*The following definitions come from  reply.c  */
  12953. +
  12954.  int reply_special(char *inbuf,char *outbuf);
  12955.  int reply_tcon(char *inbuf,char *outbuf);
  12956.  int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize);
  12957. @@ -432,6 +620,9 @@
  12958.  int reply_writebs(char *inbuf,char *outbuf);
  12959.  int reply_setattrE(char *inbuf,char *outbuf);
  12960.  int reply_getattrE(char *inbuf,char *outbuf);
  12961. +
  12962. +/*The following definitions come from  server.c  */
  12963. +
  12964.  mode_t unix_mode(int cnum,int dosmode);
  12965.  int dos_mode(int cnum,char *path,struct stat *sbuf);
  12966.  int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st);
  12967. @@ -473,6 +664,9 @@
  12968.  char *smb_fn_name(int type);
  12969.  int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
  12970.  int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
  12971. +
  12972. +/*The following definitions come from  smbencrypt.c  */
  12973. +
  12974.  void str_to_key(uchar *str,uchar *key);
  12975.  void D1(uchar *k, uchar *d, uchar *out);
  12976.  void E1(uchar *k, uchar *d, uchar *out);
  12977. @@ -481,10 +675,26 @@
  12978.  void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
  12979.  void E_md4hash(uchar *passwd, uchar *p16);
  12980.  void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
  12981. +
  12982. +/*The following definitions come from  smbpass.c  */
  12983. +
  12984. +struct smb_passwd *get_smbpwnam(char *name);
  12985. +
  12986. +/*The following definitions come from  smbpasswd.c  */
  12987. +
  12988. +
  12989. +/*The following definitions come from  smbrun.c  */
  12990. +
  12991. +
  12992. +/*The following definitions come from  status.c  */
  12993. +
  12994.  void Ucrit_addUsername(pstring username);
  12995.  unsigned int Ucrit_checkUsername(pstring username);
  12996.  void Ucrit_addPid(int pid);
  12997.  unsigned int   Ucrit_checkPid(int pid);
  12998. +
  12999. +/*The following definitions come from  system.c  */
  13000. +
  13001.  int sys_select(fd_set *fds,struct timeval *tval);
  13002.  int sys_select(fd_set *fds,struct timeval *tval);
  13003.  int sys_unlink(char *fname);
  13004. @@ -499,7 +709,16 @@
  13005.  int sys_rename(char *from, char *to);
  13006.  int sys_chown(char *fname,int uid,int gid);
  13007.  int sys_chroot(char *dname);
  13008. +
  13009. +/*The following definitions come from  testparm.c  */
  13010. +
  13011. +
  13012. +/*The following definitions come from  testprns.c  */
  13013. +
  13014.  int main(int argc, char *argv[]);
  13015. +
  13016. +/*The following definitions come from  time.c  */
  13017. +
  13018.  void GetTimeOfDay(struct timeval *tval);
  13019.  void TimeInit(void);
  13020.  int TimeDiff(time_t t);
  13021. @@ -514,20 +733,35 @@
  13022.  time_t make_unix_date3(void *date_ptr);
  13023.  BOOL set_filetime(char *fname,time_t mtime);
  13024.  char *timestring(void );
  13025. +
  13026. +/*The following definitions come from  trans2.c  */
  13027. +
  13028.  int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize);
  13029.  int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
  13030.  int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize);
  13031.  int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
  13032. +
  13033. +/*The following definitions come from  ufc.c  */
  13034. +
  13035.  char *ufc_crypt(char *key,char *salt);
  13036. +
  13037. +/*The following definitions come from  uid.c  */
  13038. +
  13039.  void init_uid(void);
  13040.  BOOL become_guest(void);
  13041.  BOOL become_user(int cnum, int uid);
  13042.  BOOL unbecome_user(void );
  13043.  int smbrun(char *cmd,char *outfile);
  13044. +
  13045. +/*The following definitions come from  username.c  */
  13046. +
  13047.  char *get_home_dir(char *user);
  13048.  void map_username(char *user);
  13049.  struct passwd *Get_Pwnam(char *user,BOOL allow_change);
  13050.  BOOL user_in_list(char *user,char *list);
  13051. +
  13052. +/*The following definitions come from  util.c  */
  13053. +
  13054.  void setup_logging(char *pname,BOOL interactive);
  13055.  void reopen_logs(void);
  13056.  BOOL is_a_socket(int fd);
  13057. @@ -634,6 +868,9 @@
  13058.  void BlockSignals(BOOL block);
  13059.  void ajt_panic(void);
  13060.  char *readdirname(void *p);
  13061. +
  13062. +/*The following definitions come from  vt_mode.c  */
  13063. +
  13064.  int    VT_Check(char    *buffer);
  13065.  int VT_Start_utmp(void);
  13066.  int VT_Stop_utmp(void);
  13067. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/reply.c samba-1.9.16alpha11/source/reply.c
  13068. --- samba-1.9.16alpha10/source/reply.c    Mon Jun 10 15:19:00 1996
  13069. +++ samba-1.9.16alpha11/source/reply.c    Mon Jul 15 17:55:06 1996
  13070. @@ -2062,6 +2062,11 @@
  13071.    cnum = SVAL(inbuf,smb_tid);
  13072.    uid = SVAL(inbuf,smb_uid);
  13073.  
  13074. +  if (!OPEN_CNUM(cnum)) {
  13075. +    DEBUG(4,("Invalid cnum in tdis (%d)\n",cnum));
  13076. +    return(ERROR(ERRSRV,ERRinvnid));
  13077. +  }
  13078. +
  13079.    Connections[cnum].used = False;
  13080.  
  13081.    close_cnum(cnum,uid);
  13082. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/smb.h samba-1.9.16alpha11/source/smb.h
  13083. --- samba-1.9.16alpha10/source/smb.h    Mon Jun 10 15:19:02 1996
  13084. +++ samba-1.9.16alpha11/source/smb.h    Thu Jul 18 20:53:16 1996
  13085. @@ -108,10 +108,16 @@
  13086.  #else
  13087.  EXTERN int syslog_level;
  13088.  
  13089. -#define DEBUG(level,body) ((DEBUGLEVEL>=(level))? \
  13090. -                           (syslog_level = (level), Debug1 body):0)
  13091. +#define DEBUG(level,body) ((DEBUGLEVEL>=(level))? (syslog_level = (level), Debug1 body):0)
  13092.  #endif
  13093.  
  13094. +/* this defines the error codes that receive_smb can put in smberrcode */
  13095. +#define SMBERR_OK 0
  13096. +#define SMBERR_TIMEOUT 1
  13097. +#define SMBERR_EOF 2
  13098. +#define SMBERR_ERROR 3
  13099. +
  13100. +
  13101.  #define DIR_STRUCT_SIZE 43
  13102.  
  13103.  /* these define all the command types recognised by the server - there
  13104. @@ -380,6 +386,15 @@
  13105.    BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
  13106.  };
  13107.  
  13108. +
  13109. +/* used for network interfaces */
  13110. +struct interface
  13111. +{
  13112. +    struct interface *next;
  13113. +    struct in_addr ip;
  13114. +    struct in_addr bcast;
  13115. +    struct in_addr nmask;
  13116. +};
  13117.  
  13118.  /* this is used for smbstatus */
  13119.  struct connect_record
  13120. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/smbpass.c samba-1.9.16alpha11/source/smbpass.c
  13121. --- samba-1.9.16alpha10/source/smbpass.c    Mon Jun 10 15:19:02 1996
  13122. +++ samba-1.9.16alpha11/source/smbpass.c    Thu Jul 18 20:53:16 1996
  13123. @@ -109,8 +109,7 @@
  13124.  /*
  13125.   * Routine to search the smbpasswd file for an entry matching the username.
  13126.   */
  13127. -struct smb_passwd *
  13128. -get_smbpwnam(char *name)
  13129. +struct smb_passwd *get_smbpwnam(char *name)
  13130.  {
  13131.      /* Static buffers we will return. */
  13132.      static struct smb_passwd pw_buf;
  13133. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/smbtar samba-1.9.16alpha11/source/smbtar
  13134. --- samba-1.9.16alpha10/source/smbtar    Sat May  4 17:50:25 1996
  13135. +++ samba-1.9.16alpha11/source/smbtar    Sun Jun 30 15:17:26 1996
  13136. @@ -138,4 +138,3 @@
  13137.  -E -N $log -D "'$cdcmd'" \
  13138.  -T${tarcmd}${tarargs} $blocksize $newer $tapefile $* $verbose
  13139.  
  13140. -
  13141. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/system.c samba-1.9.16alpha11/source/system.c
  13142. --- samba-1.9.16alpha10/source/system.c    Sun May  5 17:18:39 1996
  13143. +++ samba-1.9.16alpha11/source/system.c    Sun Jun 30 15:17:26 1996
  13144. @@ -25,13 +25,17 @@
  13145.  
  13146.  /*
  13147.     The idea is that this file will eventually have wrappers around all
  13148. -   important system calls in samba. The aim is twofold:
  13149. +   important system calls in samba. The aims are:
  13150.  
  13151.     - to enable easier porting by putting OS dependent stuff in here
  13152.  
  13153.     - to allow for hooks into other "pseudo-filesystems"
  13154.  
  13155.     - to allow easier integration of things like the japanese extensions
  13156. +
  13157. +   - to support the philosophy of Samba to expose the features of
  13158. +     the OS within the SMB model. In general whatever file/printer/variable
  13159. +     expansions/etc make sense to the OS should be acceptable to Samba.
  13160.  */
  13161.  
  13162.  
  13163. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/uninstallbin.sh samba-1.9.16alpha11/source/uninstallbin.sh
  13164. --- samba-1.9.16alpha10/source/uninstallbin.sh    Thu Jan  1 10:00:00 1970
  13165. +++ samba-1.9.16alpha11/source/uninstallbin.sh    Fri Jul  5 13:53:11 1996
  13166. @@ -0,0 +1,43 @@
  13167. +#!/bin/sh
  13168. +#4 July 96 Dan.Shearer@UniSA.edu.au   
  13169. +
  13170. +INSTALLPERMS=$1
  13171. +BASEDIR=$2
  13172. +BINDIR=$3
  13173. +LIBDIR=$4
  13174. +VARDIR=$5
  13175. +shift
  13176. +shift
  13177. +shift
  13178. +shift
  13179. +shift
  13180. +
  13181. +if [ ! -d $BINDIR ]; then
  13182. +  echo Directory $BINDIR does not exist!
  13183. +  echo Do a "make installbin" or "make install" first.
  13184. +  exit 1
  13185. +fi
  13186. +
  13187. +for p in $*; do
  13188. +  if [ ! -f $BINDIR/$p ]; then
  13189. +    echo $BINDIR/$p does not exist!
  13190. +  else
  13191. +    echo Removing $BINDIR/$p
  13192. +    rm -f $BINDIR/$p
  13193. +    if [ -f $BINDIR/$p ]; then
  13194. +      echo Cannot remove $BINDIR/$p... does $USER have privileges?
  13195. +    fi
  13196. +  fi
  13197. +done
  13198. +
  13199. +
  13200. +cat << EOF
  13201. +======================================================================
  13202. +The binaries have been uninstalled. You may restore the binaries using
  13203. +the command "make installbin" or "make install" to install binaries, 
  13204. +man pages and shell scripts. You can restore a previous version of the
  13205. +binaries (if there were any) using "make revert".
  13206. +======================================================================
  13207. +EOF
  13208. +
  13209. +exit 0
  13210. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/uninstallman.sh samba-1.9.16alpha11/source/uninstallman.sh
  13211. --- samba-1.9.16alpha10/source/uninstallman.sh    Thu Jan  1 10:00:00 1970
  13212. +++ samba-1.9.16alpha11/source/uninstallman.sh    Fri Jul  5 13:53:11 1996
  13213. @@ -0,0 +1,31 @@
  13214. +#!/bin/sh
  13215. +#4 July 96 Dan.Shearer@UniSA.edu.au
  13216. +
  13217. +MANDIR=$1
  13218. +SRCDIR=$2
  13219. +
  13220. +echo Uninstalling man pages from $MANDIR
  13221. +
  13222. +for sect in 1 5 7 8 ; do
  13223. +  for m in $MANDIR/man$sect ; do
  13224. +    for s in $SRCDIR../docs/*$sect; do
  13225. +      FNAME=$m/`basename $s`
  13226. +      if test -f $FNAME; then
  13227. +        echo Deleting $FNAME
  13228. +        rm -f $FNAME 
  13229. +        test -f $FNAME && echo Cannot remove $FNAME... does $USER have privileges?   
  13230. +      else
  13231. +        echo $FNAME does not exist! Check defines in the Makefile
  13232. +      fi
  13233. +    done
  13234. +  done
  13235. +done
  13236. +
  13237. +cat << EOF
  13238. +======================================================================
  13239. +The man pages have been uninstalled. You may install them again using 
  13240. +the command "make installman" or make "install" to install binaries,
  13241. +man pages and shell scripts.
  13242. +======================================================================
  13243. +EOF
  13244. +exit 0
  13245. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/uninstallscripts.sh samba-1.9.16alpha11/source/uninstallscripts.sh
  13246. --- samba-1.9.16alpha10/source/uninstallscripts.sh    Thu Jan  1 10:00:00 1970
  13247. +++ samba-1.9.16alpha11/source/uninstallscripts.sh    Fri Jul  5 13:53:12 1996
  13248. @@ -0,0 +1,37 @@
  13249. +#!/bin/sh
  13250. +# 5 July 96 Dan.Shearer@UniSA.Edu.Au  - almost identical to uninstallbin.sh
  13251. +
  13252. +INSTALLPERMS=$1
  13253. +BINDIR=$2
  13254. +
  13255. +shift
  13256. +shift
  13257. +
  13258. +if [ ! -d $BINDIR ]; then
  13259. +  echo Directory $BINDIR does not exist!
  13260. +  echo Do a "make installscripts" or "make install" first.
  13261. +  exit 1
  13262. +fi
  13263. +
  13264. +for p in $*; do
  13265. +  if [ ! -f $BINDIR/$p ]; then
  13266. +    echo $BINDIR/$p does not exist!
  13267. +  else
  13268. +    echo Removing $BINDIR/$p
  13269. +    rm -f $BINDIR/$p
  13270. +    if [ -f $BINDIR/$p ]; then
  13271. +      echo Cannot remove $BINDIR/$p... does $USER have privileges?
  13272. +    fi
  13273. +  fi
  13274. +done
  13275. +
  13276. +cat << EOF
  13277. +======================================================================
  13278. +The scripts have been uninstalled. You may reinstall them using
  13279. +the command "make installscripts" or "make install" to install binaries,
  13280. +man pages and shell scripts. You may recover a previous version (if any
  13281. +with "make revert".
  13282. +======================================================================
  13283. +EOF
  13284. +
  13285. +exit 0
  13286. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha10/source/version.h samba-1.9.16alpha11/source/version.h
  13287. --- samba-1.9.16alpha10/source/version.h    Mon Jun 10 15:19:48 1996
  13288. +++ samba-1.9.16alpha11/source/version.h    Thu Jul 18 20:53:51 1996
  13289. @@ -1 +1 @@
  13290. -#define VERSION "1.9.16alpha10"
  13291. +#define VERSION "1.9.16alpha11"
  13292.